Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010, Code Aurora Forum. 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 Code Aurora 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 /*============================================================================
     30                             O p e n M A X   w r a p p e r s
     31                              O p e n  M A X   C o r e
     32 
     33 *//** @file omx_vdec.cpp
     34   This module contains the implementation of the OpenMAX core & component.
     35 
     36 *//*========================================================================*/
     37 
     38 //////////////////////////////////////////////////////////////////////////////
     39 //                             Include Files
     40 //////////////////////////////////////////////////////////////////////////////
     41 
     42 #include <string.h>
     43 #include <pthread.h>
     44 #include <stdlib.h>
     45 #include <unistd.h>
     46 #include <errno.h>
     47 #include "omx_vdec.h"
     48 #include <fcntl.h>
     49 
     50 #define BITSTREAM_LOG 0
     51 
     52 #if BITSTREAM_LOG
     53 FILE *outputBufferFile1;
     54 char filename [] = "/data/input-bitstream.m4v";
     55 #endif
     56 
     57 #define H264_SUPPORTED_WIDTH (480)
     58 #define H264_SUPPORTED_HEIGHT (368)
     59 
     60 #define MPEG4_SUPPORTED_WIDTH (480)
     61 #define MPEG4_SUPPORTED_HEIGHT (368)
     62 
     63 #define VC1_SP_MP_START_CODE        0xC5000000
     64 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     65 #define VC1_AP_SEQ_START_CODE       0x0F010000
     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 #ifdef _ANDROID_
     80     extern "C"{
     81         #include<utils/Log.h>
     82     }
     83 #endif//_ANDROID_
     84 
     85 #define DEBUG_PRINT(...) printf(__VA_ARGS__)
     86 #define DEBUG_PRINT_ERROR(...) printf(__VA_ARGS__)
     87 #define DEBUG_PRINT_LOW(...) printf(__VA_ARGS__)
     88 
     89 
     90 void* async_message_thread (void *input)
     91 {
     92   struct vdec_ioctl_msg ioctl_msg;
     93   struct vdec_msginfo vdec_msg;
     94   omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
     95 
     96   DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
     97   while (1)
     98   {
     99     ioctl_msg.inputparam = NULL;
    100     ioctl_msg.outputparam = (void*)&vdec_msg;
    101 
    102     /*Wait for a message from the video decoder driver*/
    103     if (ioctl ( omx->driver_context.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,
    104                 (void*)&ioctl_msg) < 0)
    105     {
    106       DEBUG_PRINT_ERROR("\n Error in ioctl read next msg");
    107       break;
    108     }
    109     else
    110     {
    111       /*Call Instance specific process function*/
    112       if (omx->async_message_process(input,&vdec_msg) < 0)
    113       {
    114         DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message");
    115       }
    116     }
    117   }
    118   DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
    119   return NULL;
    120 }
    121 
    122 void* message_thread(void *input)
    123 {
    124   omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    125   unsigned char id;
    126   int n;
    127 
    128   DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
    129   while (1)
    130   {
    131 
    132     n = read(omx->m_pipe_in, &id, 1);
    133 
    134     if(0 == n)
    135     {
    136       break;
    137     }
    138 
    139     if (1 == n)
    140     {
    141         omx->process_event_cb(omx, id);
    142     }
    143     if ((n < 0) && (errno != EINTR))
    144     {
    145       DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
    146       break;
    147     }
    148   }
    149   DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
    150   return 0;
    151 }
    152 
    153 void post_message(omx_vdec *omx, unsigned char id)
    154 {
    155       int ret_value;
    156       DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
    157       ret_value = write(omx->m_pipe_out, &id, 1);
    158       DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
    159 }
    160 
    161 // omx_cmd_queue destructor
    162 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    163 {
    164   // Nothing to do
    165 }
    166 
    167 // omx cmd queue constructor
    168 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    169 {
    170     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    171 }
    172 
    173 // omx cmd queue insert
    174 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
    175 {
    176   bool ret = true;
    177   if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
    178   {
    179     m_q[m_write].id       = id;
    180     m_q[m_write].param1   = p1;
    181     m_q[m_write].param2   = p2;
    182     m_write++;
    183     m_size ++;
    184     if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
    185     {
    186       m_write = 0;
    187     }
    188   }
    189   else
    190   {
    191     ret = false;
    192     DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
    193   }
    194   return ret;
    195 }
    196 
    197 // omx cmd queue pop
    198 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
    199 {
    200   bool ret = true;
    201   if (m_size > 0)
    202   {
    203     *id = m_q[m_read].id;
    204     *p1 = m_q[m_read].param1;
    205     *p2 = m_q[m_read].param2;
    206     // Move the read pointer ahead
    207     ++m_read;
    208     --m_size;
    209     if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
    210     {
    211       m_read = 0;
    212     }
    213   }
    214   else
    215   {
    216     ret = false;
    217   }
    218   return ret;
    219 }
    220 
    221 // Retrieve the first mesg type in the queue
    222 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    223 {
    224     return m_q[m_read].id;
    225 }
    226 
    227 // factory function executed by the core to create instances
    228 void *get_omx_component_factory_fn(void)
    229 {
    230   return (new omx_vdec);
    231 }
    232 
    233 #ifdef _ANDROID_
    234 VideoHeap::VideoHeap(int fd, size_t size, void* base)
    235 {
    236     // dup file descriptor, map once, use pmem
    237     init(dup(fd), base, size, 0 , "/dev/pmem_adsp");
    238 }
    239 #endif // _ANDROID_
    240 
    241 /* ======================================================================
    242 FUNCTION
    243   omx_vdec::omx_vdec
    244 
    245 DESCRIPTION
    246   Constructor
    247 
    248 PARAMETERS
    249   None
    250 
    251 RETURN VALUE
    252   None.
    253 ========================================================================== */
    254 omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
    255                       m_app_data(NULL),
    256                       m_color_format(OMX_COLOR_FormatYUV420Planar),
    257                       m_inp_mem_ptr(NULL),
    258                       m_out_mem_ptr(NULL),
    259                       pending_input_buffers(0),
    260                       pending_output_buffers(0),
    261                       m_out_bm_count(0),
    262                       m_out_buf_count(0),
    263                       m_inp_buf_count(OMX_VIDEO_DEC_NUM_INPUT_BUFFERS),
    264                       m_inp_buf_size(OMX_VIDEO_DEC_INPUT_BUFFER_SIZE),
    265                       m_inp_bm_count(0),
    266                       m_inp_bPopulated(OMX_FALSE),
    267                       m_out_bPopulated(OMX_FALSE),
    268                       m_height(0),
    269                       m_width(0),
    270                       m_port_height(0),
    271                       m_port_width(0),
    272                       m_crop_x(0),
    273                       m_crop_y(0),
    274                       m_crop_dx(0),
    275                       m_crop_dy(0),
    276                       m_flags(0),
    277                       m_inp_bEnabled(OMX_TRUE),
    278                       m_out_bEnabled(OMX_TRUE),
    279                       m_event_port_settings_sent(false),
    280                       input_flush_progress (false),
    281                       output_flush_progress (false),
    282                       m_platform_list(NULL),
    283                       m_platform_entry(NULL),
    284                       m_pmem_info(NULL),
    285                       input_use_buffer (false),
    286                       output_use_buffer (false),
    287                       m_ineos_reached (0),
    288                       m_outeos_pending (0),
    289                       m_outeos_reached (0),
    290                       arbitrary_bytes (true),
    291                       psource_frame (NULL),
    292                       pdest_frame (NULL),
    293                       m_inp_heap_ptr (NULL),
    294                       m_heap_inp_bm_count (0),
    295                       codec_type_parse ((codec_type)0),
    296                       first_frame_meta (true),
    297                       frame_count (0),
    298                       nal_count (0),
    299                       nal_length(0),
    300                       look_ahead_nal (false),
    301                       first_frame(0),
    302                       first_buffer(NULL),
    303                       first_frame_size (0),
    304                       set_seq_header_done(false),
    305                       gate_output_buffers(true),
    306                       gate_input_buffers(false),
    307                       stride(0),
    308                       sent_first_frame(false),
    309                       m_error_propogated(false),
    310                       scan_lines(0),
    311                       m_device_file_ptr(NULL),
    312                       m_vc1_profile((vc1_profile_type)0)
    313 {
    314   /* Assumption is that , to begin with , we have all the frames with decoder */
    315   DEBUG_PRINT_HIGH("\n In OMX vdec Constuctor");
    316   memset(&m_cmp,0,sizeof(m_cmp));
    317   memset(&m_cb,0,sizeof(m_cb));
    318   memset (&driver_context,0,sizeof(driver_context));
    319   memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    320   memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    321   driver_context.video_driver_fd = -1;
    322   m_vendor_config.pData = NULL;
    323   pthread_mutex_init(&m_lock, NULL);
    324   sem_init(&m_cmd_lock,0,0);
    325 }
    326 
    327 
    328 /* ======================================================================
    329 FUNCTION
    330   omx_vdec::~omx_vdec
    331 
    332 DESCRIPTION
    333   Destructor
    334 
    335 PARAMETERS
    336   None
    337 
    338 RETURN VALUE
    339   None.
    340 ========================================================================== */
    341 omx_vdec::~omx_vdec()
    342 {
    343   m_pmem_info = NULL;
    344   m_port_width = m_port_height = 0;
    345   DEBUG_PRINT_HIGH("\n In OMX vdec Destructor");
    346   if(m_pipe_in) close(m_pipe_in);
    347   if(m_pipe_out) close(m_pipe_out);
    348   m_pipe_in = -1;
    349   m_pipe_out = -1;
    350   DEBUG_PRINT_HIGH("\n Waiting on OMX Msg Thread exit");
    351   pthread_join(msg_thread_id,NULL);
    352   DEBUG_PRINT_HIGH("\n Waiting on OMX Async Thread exit");
    353   pthread_join(async_thread_id,NULL);
    354   pthread_mutex_destroy(&m_lock);
    355   sem_destroy(&m_cmd_lock);
    356   DEBUG_PRINT_HIGH("\n Exit OMX vdec Destructor");
    357 }
    358 
    359 /* ======================================================================
    360 FUNCTION
    361   omx_vdec::OMXCntrlProcessMsgCb
    362 
    363 DESCRIPTION
    364   IL Client callbacks are generated through this routine. The decoder
    365   provides the thread context for this routine.
    366 
    367 PARAMETERS
    368   ctxt -- Context information related to the self.
    369   id   -- Event identifier. This could be any of the following:
    370           1. Command completion event
    371           2. Buffer done callback event
    372           3. Frame done callback event
    373 
    374 RETURN VALUE
    375   None.
    376 
    377 ========================================================================== */
    378 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
    379 {
    380   unsigned p1; // Parameter - 1
    381   unsigned p2; // Parameter - 2
    382   unsigned ident;
    383   unsigned qsize=0; // qsize
    384   omx_vdec *pThis = (omx_vdec *) ctxt;
    385 
    386   if(!pThis)
    387   {
    388     DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
    389         __func__);
    390     return;
    391   }
    392 
    393   // Protect the shared queue data structure
    394   do
    395   {
    396     /*Read the message id's from the queue*/
    397     pthread_mutex_lock(&pThis->m_lock);
    398     qsize = pThis->m_cmd_q.m_size;
    399     if(qsize)
    400     {
    401       pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
    402     }
    403 
    404     if (qsize == 0 && !pThis->gate_output_buffers)
    405     {
    406       qsize = pThis->m_ftb_q.m_size;
    407       if (qsize)
    408       {
    409         pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
    410       }
    411     }
    412 
    413     if (qsize == 0)
    414     {
    415       qsize = pThis->m_etb_q.m_size;
    416       if (qsize)
    417       {
    418         pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
    419       }
    420     }
    421     pthread_mutex_unlock(&pThis->m_lock);
    422 
    423     /*process message if we have one*/
    424     if(qsize > 0)
    425     {
    426       id = ident;
    427       switch (id)
    428       {
    429         case OMX_COMPONENT_GENERATE_EVENT:
    430           if (pThis->m_cb.EventHandler)
    431           {
    432             switch (p1)
    433             {
    434               case OMX_CommandStateSet:
    435                 pThis->m_state = (OMX_STATETYPE) p2;
    436                 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
    437                     pThis->m_state);
    438                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    439                                       OMX_EventCmdComplete, p1, p2, NULL);
    440                 break;
    441 
    442               case OMX_EventError:
    443                 if(p2 == OMX_StateInvalid)
    444                 {
    445                     DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
    446                     pThis->m_state = (OMX_STATETYPE) p2;
    447                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    448                                OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    449                 }
    450                 else if (p2 == (unsigned)OMX_ErrorHardware)
    451                 {
    452                    pThis->omx_report_error();
    453                 }
    454                 else
    455                 {
    456                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    457                                       OMX_EventError, p2, NULL, NULL );
    458                 }
    459                 break;
    460 
    461               case OMX_CommandPortDisable:
    462                 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
    463                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    464                                       OMX_EventCmdComplete, p1, p2, NULL );
    465                 //TODO: Check if output port is one that got disabled
    466                 pThis->gate_output_buffers = false;
    467                 break;
    468               case OMX_CommandPortEnable:
    469                 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
    470                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    471                                       OMX_EventCmdComplete, p1, p2, NULL );
    472                 break;
    473 
    474               default:
    475                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    476                                          OMX_EventCmdComplete, p1, p2, NULL );
    477                 break;
    478 
    479             }
    480           }
    481           else
    482           {
    483             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
    484           }
    485           break;
    486         case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
    487           if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
    488               (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    489           {
    490             DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
    491             pThis->omx_report_error ();
    492           }
    493       break;
    494         case OMX_COMPONENT_GENERATE_ETB:
    495           if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    496               (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    497           {
    498             DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
    499             pThis->omx_report_error ();
    500           }
    501          break;
    502 
    503         case OMX_COMPONENT_GENERATE_FTB:
    504           if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    505                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    506           {
    507              DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
    508              pThis->omx_report_error ();
    509           }
    510         break;
    511 
    512         case OMX_COMPONENT_GENERATE_COMMAND:
    513           pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    514                                     (OMX_U32)p2,(OMX_PTR)NULL);
    515           break;
    516 
    517         case OMX_COMPONENT_GENERATE_EBD:
    518 
    519           if (p2 != VDEC_S_SUCCESS)
    520           {
    521             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
    522             pThis->omx_report_error ();
    523           }
    524           else
    525           {
    526             if ( pThis->empty_buffer_done(&pThis->m_cmp,
    527                  (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
    528             {
    529                DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
    530                pThis->omx_report_error ();
    531             }
    532           }
    533           break;
    534 
    535         case OMX_COMPONENT_GENERATE_FBD:
    536           if (p2 != VDEC_S_SUCCESS)
    537           {
    538             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
    539             pThis->omx_report_error ();
    540           }
    541           else
    542           {
    543              if ( pThis->fill_buffer_done(&pThis->m_cmp,
    544                   (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
    545              {
    546                DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
    547                pThis->omx_report_error ();
    548              }
    549           }
    550           break;
    551 
    552         case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
    553           DEBUG_PRINT_HIGH("\n Flush i/p Port complete");
    554           pThis->input_flush_progress = false;
    555           DEBUG_PRINT_LOW("\n Input flush done pending input %d",
    556                              pThis->pending_input_buffers);
    557 
    558           if (pThis->m_cb.EventHandler)
    559           {
    560             if (p2 != VDEC_S_SUCCESS)
    561             {
    562               DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
    563               pThis->omx_report_error ();
    564             }
    565             else
    566             {
    567               /*Check if we need generate event for Flush done*/
    568               if(BITMASK_PRESENT(&pThis->m_flags,
    569                                  OMX_COMPONENT_INPUT_FLUSH_PENDING))
    570               {
    571                 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
    572                 DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
    573                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    574                                          OMX_EventCmdComplete,OMX_CommandFlush,
    575                                          OMX_CORE_INPUT_PORT_INDEX,NULL );
    576               }
    577               if (BITMASK_PRESENT(&pThis->m_flags,
    578                                        OMX_COMPONENT_IDLE_PENDING))
    579               {
    580                 if (!pThis->output_flush_progress)
    581                 {
    582                    DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
    583                    if (ioctl (pThis->driver_context.video_driver_fd,
    584                               VDEC_IOCTL_CMD_STOP,NULL ) < 0)
    585                    {
    586                      DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
    587                      pThis->omx_report_error ();
    588                    }
    589                 }
    590               }
    591             }
    592           }
    593 
    594           break;
    595 
    596         case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
    597         DEBUG_PRINT_HIGH("\n Flush o/p Port complete");
    598         pThis->output_flush_progress = false;
    599         DEBUG_PRINT_LOW("\n Output flush done pending buf %d",pThis->pending_output_buffers);
    600 
    601         if (pThis->m_cb.EventHandler)
    602         {
    603           if (p2 != VDEC_S_SUCCESS)
    604           {
    605             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
    606             pThis->omx_report_error ();
    607           }
    608           else
    609           {
    610             /*Check if we need generate event for Flush done*/
    611             if(BITMASK_PRESENT(&pThis->m_flags,
    612                                OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
    613             {
    614               DEBUG_PRINT_LOW("\n Notify Output Flush done");
    615               BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
    616 
    617               pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    618                                        OMX_EventCmdComplete,OMX_CommandFlush,
    619                                        OMX_CORE_OUTPUT_PORT_INDEX,NULL );
    620             }
    621             if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
    622             {
    623               if (!pThis->input_flush_progress)
    624               {
    625                 DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
    626                 if (ioctl (pThis->driver_context.video_driver_fd,
    627                            VDEC_IOCTL_CMD_STOP,NULL ) < 0)
    628                 {
    629                   DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
    630                   pThis->omx_report_error ();
    631                 }
    632               }
    633             }
    634           }
    635         }
    636         break;
    637 
    638         case OMX_COMPONENT_GENERATE_START_DONE:
    639           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
    640 
    641           if (pThis->m_cb.EventHandler)
    642           {
    643             if (p2 != VDEC_S_SUCCESS)
    644             {
    645               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
    646               pThis->omx_report_error ();
    647             }
    648             else
    649             {
    650               DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
    651               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
    652               {
    653                 DEBUG_PRINT_LOW("\n Move to executing");
    654                 // Send the callback now
    655                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    656                 pThis->m_state = OMX_StateExecuting;
    657                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    658                                        OMX_EventCmdComplete,OMX_CommandStateSet,
    659                                        OMX_StateExecuting, NULL);
    660               }
    661               else if (BITMASK_PRESENT(&pThis->m_flags,
    662                                        OMX_COMPONENT_PAUSE_PENDING))
    663               {
    664                 if (ioctl (pThis->driver_context.video_driver_fd,
    665                            VDEC_IOCTL_CMD_PAUSE,NULL ) < 0)
    666                 {
    667                   DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
    668                   pThis->omx_report_error ();
    669                 }
    670               }
    671             }
    672           }
    673           else
    674           {
    675             DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
    676           }
    677           break;
    678 
    679         case OMX_COMPONENT_GENERATE_PAUSE_DONE:
    680           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
    681           if (pThis->m_cb.EventHandler)
    682           {
    683             if (p2 != VDEC_S_SUCCESS)
    684             {
    685               DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
    686               pThis->omx_report_error ();
    687             }
    688             else
    689             {
    690               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
    691               {
    692                 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
    693                 //Send the callback now
    694                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
    695                 pThis->m_state = OMX_StatePause;
    696                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    697                                        OMX_EventCmdComplete,OMX_CommandStateSet,
    698                                        OMX_StatePause, NULL);
    699               }
    700             }
    701           }
    702 
    703           break;
    704 
    705         case OMX_COMPONENT_GENERATE_RESUME_DONE:
    706           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
    707           if (pThis->m_cb.EventHandler)
    708           {
    709             if (p2 != VDEC_S_SUCCESS)
    710             {
    711               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
    712               pThis->omx_report_error ();
    713             }
    714             else
    715             {
    716               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
    717               {
    718                 DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
    719                 // Send the callback now
    720                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
    721                 pThis->m_state = OMX_StateExecuting;
    722                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    723                                        OMX_EventCmdComplete,OMX_CommandStateSet,
    724                                        OMX_StateExecuting,NULL);
    725               }
    726             }
    727           }
    728 
    729           break;
    730 
    731         case OMX_COMPONENT_GENERATE_STOP_DONE:
    732           DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
    733           if (pThis->m_cb.EventHandler)
    734           {
    735             if (p2 != VDEC_S_SUCCESS)
    736             {
    737               DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
    738               pThis->omx_report_error ();
    739             }
    740             else
    741             {
    742               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
    743               {
    744                 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
    745                 // Send the callback now
    746                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
    747                 pThis->m_state = OMX_StateIdle;
    748                 DEBUG_PRINT_LOW("\n Move to Idle State");
    749                 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
    750                                        OMX_EventCmdComplete,OMX_CommandStateSet,
    751                                          OMX_StateIdle,NULL);
    752               }
    753             }
    754           }
    755 
    756           break;
    757 
    758         case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
    759           DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
    760           pThis->omx_report_error ();
    761           break;
    762 
    763         default:
    764           break;
    765         }
    766       }
    767     pthread_mutex_lock(&pThis->m_lock);
    768     if(!pThis->gate_output_buffers)
    769     {
    770     qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
    771             pThis->m_etb_q.m_size;
    772     }
    773     else
    774     {
    775       qsize = pThis->m_cmd_q.m_size + pThis->m_etb_q.m_size;
    776     }
    777     pthread_mutex_unlock(&pThis->m_lock);
    778   }
    779   while(qsize>0);
    780 
    781 }
    782 
    783 
    784 
    785 /* ======================================================================
    786 FUNCTION
    787   omx_vdec::ComponentInit
    788 
    789 DESCRIPTION
    790   Initialize the component.
    791 
    792 PARAMETERS
    793   ctxt -- Context information related to the self.
    794   id   -- Event identifier. This could be any of the following:
    795           1. Command completion event
    796           2. Buffer done callback event
    797           3. Frame done callback event
    798 
    799 RETURN VALUE
    800   None.
    801 
    802 ========================================================================== */
    803 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
    804 {
    805 
    806   OMX_ERRORTYPE eRet = OMX_ErrorNone;
    807   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
    808   unsigned int   alignment = 0,buffer_size = 0;
    809   int fds[2];
    810   int r;
    811    bool is_fluid = false;
    812 
    813   if (!m_device_file_ptr) {
    814     int bytes_read = 0,count = 0;
    815     unsigned min_size;
    816     m_device_file_ptr = fopen("/sys/devices/system/soc/soc0/hw_platform","rb");
    817     if (m_device_file_ptr) {
    818       (void)fgets((char *)m_hwdevice_name,sizeof(m_hwdevice_name),m_device_file_ptr);
    819       DEBUG_PRINT_HIGH ("\n Name of the device is %s",m_hwdevice_name);
    820       min_size = strnlen((const char *)m_hwdevice_name,sizeof(m_hwdevice_name));
    821       if (strlen("Fluid") < min_size) {
    822           min_size = strnlen("Fluid",sizeof("Fluid"));
    823       }
    824       if  (!strncmp("Fluid",(const char *)m_hwdevice_name,min_size)) {
    825         is_fluid = true;
    826       }
    827       fclose (m_device_file_ptr);
    828     } else {
    829       DEBUG_PRINT_HIGH("\n Could not open hw_platform file");
    830     }
    831   }
    832 
    833   DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Start of New Playback");
    834   driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
    835                       O_RDWR|O_NONBLOCK);
    836 
    837   DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d",
    838                    driver_context.video_driver_fd);
    839 
    840   if(driver_context.video_driver_fd == 0){
    841     driver_context.video_driver_fd = open ("/dev/msm_vidc_dec",\
    842                       O_RDWR|O_NONBLOCK);
    843   }
    844 
    845   if(driver_context.video_driver_fd < 0)
    846   {
    847     DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure\n");
    848     return OMX_ErrorInsufficientResources;
    849   }
    850 
    851 #ifndef MULTI_DEC_INST
    852   unsigned int instance_count = 0;
    853   if (!is_fluid) {
    854     ioctl_msg.outputparam = &instance_count;
    855     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_NUMBER_INSTANCES,
    856                (void*)&ioctl_msg) < 0){
    857         DEBUG_PRINT_ERROR("\n Instance Query Failed");
    858         return OMX_ErrorInsufficientResources;
    859     }
    860     if (instance_count > 1) {
    861       close(driver_context.video_driver_fd);
    862       DEBUG_PRINT_ERROR("\n Reject Second instance of Decoder");
    863       driver_context.video_driver_fd = -1;
    864       return OMX_ErrorInsufficientResources;
    865     }
    866   }
    867 #endif
    868 
    869 #if BITSTREAM_LOG
    870   outputBufferFile1 = fopen (filename, "ab");
    871 #endif
    872 
    873   // Copy the role information which provides the decoder kind
    874   strncpy(driver_context.kind,role,128);
    875 
    876   if(!strncmp(driver_context.kind,"OMX.qcom.video.decoder.mpeg4",\
    877       OMX_MAX_STRINGNAME_SIZE))
    878   {
    879      strncpy((char *)m_cRole, "video_decoder.mpeg4",\
    880      OMX_MAX_STRINGNAME_SIZE);
    881      driver_context.decoder_format = VDEC_CODECTYPE_MPEG4;
    882      eCompressionFormat = OMX_VIDEO_CodingMPEG4;
    883      /*Initialize Start Code for MPEG4*/
    884      codec_type_parse = CODEC_TYPE_MPEG4;
    885      m_frame_parser.init_start_codes (codec_type_parse);
    886   }
    887   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",\
    888          OMX_MAX_STRINGNAME_SIZE))
    889   {
    890      strncpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
    891      DEBUG_PRINT_LOW("\n H263 Decoder selected");
    892      driver_context.decoder_format = VDEC_CODECTYPE_H263;
    893      eCompressionFormat = OMX_VIDEO_CodingH263;
    894      codec_type_parse = CODEC_TYPE_H263;
    895      m_frame_parser.init_start_codes (codec_type_parse);
    896   }
    897   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",\
    898          OMX_MAX_STRINGNAME_SIZE))
    899   {
    900     strncpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
    901     driver_context.decoder_format = VDEC_CODECTYPE_H264;
    902     eCompressionFormat = OMX_VIDEO_CodingAVC;
    903     codec_type_parse = CODEC_TYPE_H264;
    904     m_frame_parser.init_start_codes (codec_type_parse);
    905     m_frame_parser.init_nal_length(nal_length);
    906   }
    907   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",\
    908          OMX_MAX_STRINGNAME_SIZE))
    909   {
    910     strncpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
    911     driver_context.decoder_format = VDEC_CODECTYPE_VC1;
    912     eCompressionFormat = OMX_VIDEO_CodingWMV;
    913     codec_type_parse = CODEC_TYPE_VC1;
    914     m_frame_parser.init_start_codes (codec_type_parse);
    915   }
    916   else
    917   {
    918     DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
    919     eRet = OMX_ErrorInvalidComponentName;
    920   }
    921 
    922   if (eRet == OMX_ErrorNone)
    923   {
    924     driver_context.output_format = VDEC_YUV_FORMAT_NV12;
    925 
    926     if  (is_fluid) {
    927 
    928          FILE * pFile;
    929          char disable_overlay = '0';
    930          pFile = fopen
    931          ("/data/data/com.arcsoft.videowall/files/disableoverlay.txt", "rb" );
    932          if (pFile == NULL) {
    933            DEBUG_PRINT_HIGH(" fopen FAiLED  for disableoverlay.txt\n");
    934          } else {
    935             int count  = fread(&disable_overlay, 1, 1, pFile);
    936             fclose(pFile);
    937          }
    938 
    939          if(disable_overlay == '1') {
    940              DEBUG_PRINT_HIGH(" vdec : TILE format \n");
    941              driver_context.output_format = VDEC_YUV_FORMAT_TILE_4x2;
    942          } else {
    943              DEBUG_PRINT_HIGH("  vdec : NV 12 format \n");
    944              driver_context.output_format = VDEC_YUV_FORMAT_NV12;
    945          }
    946       }
    947 
    948     /*Initialize Decoder with codec type and resolution*/
    949     ioctl_msg.inputparam = &driver_context.decoder_format;
    950     ioctl_msg.outputparam = NULL;
    951 
    952     if ( (eRet == OMX_ErrorNone) &&
    953          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_CODEC,
    954                 (void*)&ioctl_msg) < 0)
    955 
    956     {
    957       DEBUG_PRINT_ERROR("\n Set codec type failed");
    958       eRet = OMX_ErrorInsufficientResources;
    959     }
    960 
    961     /*Set the output format*/
    962     ioctl_msg.inputparam = &driver_context.output_format;
    963     ioctl_msg.outputparam = NULL;
    964 
    965     if ( (eRet == OMX_ErrorNone) &&
    966          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT,
    967            (void*)&ioctl_msg) < 0)
    968     {
    969       DEBUG_PRINT_ERROR("\n Set output format failed");
    970       eRet = OMX_ErrorInsufficientResources;
    971     }
    972 
    973 #ifdef MAX_RES_720P
    974     driver_context.video_resoultion.frame_height = 720;
    975     driver_context.video_resoultion.frame_width = 1280;
    976     driver_context.video_resoultion.stride = 1280;
    977     driver_context.video_resoultion.scan_lines = 720;
    978 #endif
    979 #ifdef MAX_RES_1080P
    980     driver_context.video_resoultion.frame_height = 1088;
    981     driver_context.video_resoultion.frame_width = 1920;
    982     driver_context.video_resoultion.stride = 1920;
    983     driver_context.video_resoultion.scan_lines = 1088;
    984 #endif
    985 
    986     ioctl_msg.inputparam = &driver_context.video_resoultion;
    987     ioctl_msg.outputparam = NULL;
    988 
    989     if ( (eRet == OMX_ErrorNone) &&
    990         ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
    991            (void*)&ioctl_msg) < 0)
    992     {
    993       DEBUG_PRINT_ERROR("\n Set Resolution failed");
    994       eRet = OMX_ErrorInsufficientResources;
    995     }
    996 
    997     /*Get the Buffer requirements for input and output ports*/
    998     driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
    999     ioctl_msg.inputparam = NULL;
   1000     ioctl_msg.outputparam = &driver_context.input_buffer;
   1001 
   1002     if ( (eRet == OMX_ErrorNone) &&
   1003          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
   1004            (void*)&ioctl_msg) < 0)
   1005     {
   1006       DEBUG_PRINT_ERROR("\n Requesting for input buffer requirements failed");
   1007       eRet = OMX_ErrorInsufficientResources;
   1008     }
   1009 
   1010     m_inp_buf_count = driver_context.input_buffer.actualcount;
   1011     buffer_size = driver_context.input_buffer.buffer_size;
   1012     alignment = driver_context.input_buffer.alignment;
   1013     m_inp_buf_size = ((buffer_size + alignment -1 ) & (~(alignment -1)));
   1014     m_inp_buf_count_min = driver_context.input_buffer.mincount;
   1015 
   1016     /*Get the Buffer requirements for input and output ports*/
   1017     driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   1018     ioctl_msg.inputparam = &driver_context.input_buffer;
   1019     ioctl_msg.outputparam = NULL;
   1020 
   1021     m_inp_buf_count_min = m_inp_buf_count = driver_context.input_buffer.actualcount =
   1022      driver_context.input_buffer.mincount + 3;
   1023 
   1024     if ( (eRet == OMX_ErrorNone) &&
   1025          ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
   1026            (void*)&ioctl_msg) < 0)
   1027     {
   1028       DEBUG_PRINT_ERROR("\n Set input buffer requirements failed");
   1029       eRet = OMX_ErrorInsufficientResources;
   1030     }
   1031 
   1032 
   1033     driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   1034     ioctl_msg.inputparam = NULL;
   1035     ioctl_msg.outputparam = &driver_context.output_buffer;
   1036 
   1037     if ((eRet == OMX_ErrorNone) &&
   1038         ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
   1039            (void*)&ioctl_msg) < 0)
   1040     {
   1041       DEBUG_PRINT_ERROR("\n Requesting for output buffer requirements failed");
   1042       eRet = OMX_ErrorInsufficientResources;
   1043     }
   1044 
   1045     m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount;
   1046     m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount;
   1047 
   1048     alignment = driver_context.output_buffer.alignment;
   1049     buffer_size = driver_context.output_buffer.buffer_size;
   1050     m_out_buf_size_recon = m_out_buf_size =
   1051       ((buffer_size + alignment - 1) & (~(alignment -1)));
   1052 #ifdef MAX_RES_720P
   1053     scan_lines = m_crop_dy = m_height = 720;
   1054     stride = m_crop_dx = m_width = 1280;
   1055 #endif
   1056 #ifdef MAX_RES_1080P
   1057     scan_lines = m_crop_dy = m_height = 1088;
   1058     stride = m_crop_dx = m_width = 1920;
   1059 #endif
   1060     m_port_height             = m_height;
   1061     m_port_width              = m_width;
   1062     m_state                   = OMX_StateLoaded;
   1063 
   1064     if(pipe(fds))
   1065     {
   1066       DEBUG_PRINT_ERROR("pipe creation failed\n");
   1067       eRet = OMX_ErrorInsufficientResources;
   1068     }
   1069     else
   1070     {
   1071       int temp1[2];
   1072       if(fds[0] == 0 || fds[1] == 0)
   1073       {
   1074         if (pipe (temp1))
   1075         {
   1076           DEBUG_PRINT_ERROR("pipe creation failed\n");
   1077           return OMX_ErrorInsufficientResources;
   1078         }
   1079         //close (fds[0]);
   1080         //close (fds[1]);
   1081         fds[0] = temp1 [0];
   1082         fds[1] = temp1 [1];
   1083       }
   1084       m_pipe_in = fds[0];
   1085       m_pipe_out = fds[1];
   1086       r = pthread_create(&msg_thread_id,0,message_thread,this);
   1087 
   1088       if(r < 0)
   1089       {
   1090         DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
   1091         eRet = OMX_ErrorInsufficientResources;
   1092       }
   1093       else
   1094       {
   1095         r = pthread_create(&async_thread_id,0,async_message_thread,this);
   1096         if(r < 0)
   1097         {
   1098           DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed");
   1099           eRet = OMX_ErrorInsufficientResources;
   1100         }
   1101       }
   1102     }
   1103   }
   1104 
   1105   if (eRet != OMX_ErrorNone)
   1106   {
   1107     DEBUG_PRINT_ERROR("\n Component Init Failed");
   1108     DEBUG_PRINT_HIGH("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
   1109     (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   1110         NULL);
   1111     DEBUG_PRINT_HIGH("\n Calling close() on Video Driver");
   1112     close (driver_context.video_driver_fd);
   1113     driver_context.video_driver_fd = -1;
   1114   }
   1115   else
   1116   {
   1117     DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
   1118   }
   1119 
   1120   return eRet;
   1121 }
   1122 
   1123 /* ======================================================================
   1124 FUNCTION
   1125   omx_vdec::GetComponentVersion
   1126 
   1127 DESCRIPTION
   1128   Returns the component version.
   1129 
   1130 PARAMETERS
   1131   TBD.
   1132 
   1133 RETURN VALUE
   1134   OMX_ErrorNone.
   1135 
   1136 ========================================================================== */
   1137 OMX_ERRORTYPE  omx_vdec::get_component_version
   1138                                      (
   1139                                       OMX_IN OMX_HANDLETYPE hComp,
   1140                                       OMX_OUT OMX_STRING componentName,
   1141                                       OMX_OUT OMX_VERSIONTYPE* componentVersion,
   1142                                       OMX_OUT OMX_VERSIONTYPE* specVersion,
   1143                                       OMX_OUT OMX_UUIDTYPE* componentUUID
   1144                                       )
   1145 {
   1146     if(m_state == OMX_StateInvalid)
   1147     {
   1148         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
   1149         return OMX_ErrorInvalidState;
   1150     }
   1151   /* TBD -- Return the proper version */
   1152   return OMX_ErrorNone;
   1153 }
   1154 /* ======================================================================
   1155 FUNCTION
   1156   omx_vdec::SendCommand
   1157 
   1158 DESCRIPTION
   1159   Returns zero if all the buffers released..
   1160 
   1161 PARAMETERS
   1162   None.
   1163 
   1164 RETURN VALUE
   1165   true/false
   1166 
   1167 ========================================================================== */
   1168 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   1169                                       OMX_IN OMX_COMMANDTYPE cmd,
   1170                                       OMX_IN OMX_U32 param1,
   1171                                       OMX_IN OMX_PTR cmdData
   1172                                       )
   1173 {
   1174     DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
   1175     if(m_state == OMX_StateInvalid)
   1176     {
   1177         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
   1178         return OMX_ErrorInvalidState;
   1179     }
   1180     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   1181     sem_wait(&m_cmd_lock);
   1182     DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
   1183     return OMX_ErrorNone;
   1184 }
   1185 
   1186 /* ======================================================================
   1187 FUNCTION
   1188   omx_vdec::SendCommand
   1189 
   1190 DESCRIPTION
   1191   Returns zero if all the buffers released..
   1192 
   1193 PARAMETERS
   1194   None.
   1195 
   1196 RETURN VALUE
   1197   true/false
   1198 
   1199 ========================================================================== */
   1200 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   1201                                             OMX_IN OMX_COMMANDTYPE cmd,
   1202                                             OMX_IN OMX_U32 param1,
   1203                                             OMX_IN OMX_PTR cmdData
   1204                                             )
   1205 {
   1206   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1207   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   1208   int bFlag = 1,sem_posted = 0;;
   1209 
   1210   DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
   1211   DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
   1212     m_state, eState);
   1213 
   1214   if(cmd == OMX_CommandStateSet)
   1215   {
   1216     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
   1217     DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
   1218     /***************************/
   1219     /* Current State is Loaded */
   1220     /***************************/
   1221     if(m_state == OMX_StateLoaded)
   1222     {
   1223       if(eState == OMX_StateIdle)
   1224       {
   1225         //if all buffers are allocated or all ports disabled
   1226         if(allocate_done() ||
   1227           (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
   1228         {
   1229           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
   1230         }
   1231         else
   1232         {
   1233           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
   1234           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   1235           // Skip the event notification
   1236           bFlag = 0;
   1237         }
   1238       }
   1239       /* Requesting transition from Loaded to Loaded */
   1240       else if(eState == OMX_StateLoaded)
   1241       {
   1242         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
   1243         post_event(OMX_EventError,OMX_ErrorSameState,\
   1244                    OMX_COMPONENT_GENERATE_EVENT);
   1245         eRet = OMX_ErrorSameState;
   1246       }
   1247       /* Requesting transition from Loaded to WaitForResources */
   1248       else if(eState == OMX_StateWaitForResources)
   1249       {
   1250         /* Since error is None , we will post an event
   1251            at the end of this function definition */
   1252         DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
   1253       }
   1254       /* Requesting transition from Loaded to Executing */
   1255       else if(eState == OMX_StateExecuting)
   1256       {
   1257         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
   1258         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1259                    OMX_COMPONENT_GENERATE_EVENT);
   1260         eRet = OMX_ErrorIncorrectStateTransition;
   1261       }
   1262       /* Requesting transition from Loaded to Pause */
   1263       else if(eState == OMX_StatePause)
   1264       {
   1265         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
   1266         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1267                    OMX_COMPONENT_GENERATE_EVENT);
   1268         eRet = OMX_ErrorIncorrectStateTransition;
   1269       }
   1270       /* Requesting transition from Loaded to Invalid */
   1271       else if(eState == OMX_StateInvalid)
   1272       {
   1273         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
   1274         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1275         eRet = OMX_ErrorInvalidState;
   1276       }
   1277       else
   1278       {
   1279         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
   1280                           eState);
   1281         eRet = OMX_ErrorBadParameter;
   1282       }
   1283     }
   1284 
   1285     /***************************/
   1286     /* Current State is IDLE */
   1287     /***************************/
   1288     else if(m_state == OMX_StateIdle)
   1289     {
   1290       if(eState == OMX_StateLoaded)
   1291       {
   1292         if(release_done())
   1293         {
   1294           /*
   1295              Since error is None , we will post an event at the end
   1296              of this function definition
   1297           */
   1298           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
   1299         }
   1300         else
   1301         {
   1302           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
   1303           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   1304           // Skip the event notification
   1305           bFlag = 0;
   1306         }
   1307       }
   1308       /* Requesting transition from Idle to Executing */
   1309       else if(eState == OMX_StateExecuting)
   1310       {
   1311         BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
   1312         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   1313         post_event (NULL,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_START_DONE);
   1314         bFlag = 0;
   1315       }
   1316       /* Requesting transition from Idle to Idle */
   1317       else if(eState == OMX_StateIdle)
   1318       {
   1319         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
   1320         post_event(OMX_EventError,OMX_ErrorSameState,\
   1321                    OMX_COMPONENT_GENERATE_EVENT);
   1322         eRet = OMX_ErrorSameState;
   1323       }
   1324       /* Requesting transition from Idle to WaitForResources */
   1325       else if(eState == OMX_StateWaitForResources)
   1326       {
   1327         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
   1328         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1329                    OMX_COMPONENT_GENERATE_EVENT);
   1330         eRet = OMX_ErrorIncorrectStateTransition;
   1331       }
   1332        /* Requesting transition from Idle to Pause */
   1333        else if(eState == OMX_StatePause)
   1334       {
   1335          /*To pause the Video core we need to start the driver*/
   1336          if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_START,
   1337                     NULL) < 0)
   1338          {
   1339            DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
   1340            omx_report_error ();
   1341            eRet = OMX_ErrorHardware;
   1342          }
   1343          else
   1344          {
   1345            BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   1346            DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
   1347            bFlag = 0;
   1348          }
   1349       }
   1350       /* Requesting transition from Idle to Invalid */
   1351        else if(eState == OMX_StateInvalid)
   1352       {
   1353         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
   1354         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1355         eRet = OMX_ErrorInvalidState;
   1356       }
   1357       else
   1358       {
   1359         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
   1360         eRet = OMX_ErrorBadParameter;
   1361       }
   1362     }
   1363 
   1364     /******************************/
   1365     /* Current State is Executing */
   1366     /******************************/
   1367     else if(m_state == OMX_StateExecuting)
   1368     {
   1369        DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
   1370        /* Requesting transition from Executing to Idle */
   1371        if(eState == OMX_StateIdle)
   1372        {
   1373          /* Since error is None , we will post an event
   1374          at the end of this function definition
   1375          */
   1376          DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
   1377          BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   1378          if(!sem_posted)
   1379          {
   1380            sem_posted = 1;
   1381            sem_post (&m_cmd_lock);
   1382            execute_omx_flush(OMX_ALL);
   1383          }
   1384          bFlag = 0;
   1385        }
   1386        /* Requesting transition from Executing to Paused */
   1387        else if(eState == OMX_StatePause)
   1388        {
   1389          DEBUG_PRINT_LOW("\n PAUSE Command Issued");
   1390          if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
   1391                     NULL) < 0)
   1392          {
   1393            DEBUG_PRINT_ERROR("\n Error In Pause State");
   1394            post_event(OMX_EventError,OMX_ErrorHardware,\
   1395                       OMX_COMPONENT_GENERATE_EVENT);
   1396            eRet = OMX_ErrorHardware;
   1397          }
   1398          else
   1399          {
   1400            BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   1401            DEBUG_PRINT_LOW("send_command_proxy(): Pause-->Executing\n");
   1402            bFlag = 0;
   1403          }
   1404        }
   1405        /* Requesting transition from Executing to Loaded */
   1406        else if(eState == OMX_StateLoaded)
   1407        {
   1408          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
   1409          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1410                     OMX_COMPONENT_GENERATE_EVENT);
   1411          eRet = OMX_ErrorIncorrectStateTransition;
   1412        }
   1413        /* Requesting transition from Executing to WaitForResources */
   1414        else if(eState == OMX_StateWaitForResources)
   1415        {
   1416          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
   1417          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1418                     OMX_COMPONENT_GENERATE_EVENT);
   1419          eRet = OMX_ErrorIncorrectStateTransition;
   1420        }
   1421        /* Requesting transition from Executing to Executing */
   1422        else if(eState == OMX_StateExecuting)
   1423        {
   1424          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
   1425          post_event(OMX_EventError,OMX_ErrorSameState,\
   1426                     OMX_COMPONENT_GENERATE_EVENT);
   1427          eRet = OMX_ErrorSameState;
   1428        }
   1429        /* Requesting transition from Executing to Invalid */
   1430        else if(eState == OMX_StateInvalid)
   1431        {
   1432          DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
   1433          post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1434          eRet = OMX_ErrorInvalidState;
   1435        }
   1436        else
   1437        {
   1438          DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
   1439          eRet = OMX_ErrorBadParameter;
   1440        }
   1441     }
   1442     /***************************/
   1443     /* Current State is Pause  */
   1444     /***************************/
   1445     else if(m_state == OMX_StatePause)
   1446     {
   1447       /* Requesting transition from Pause to Executing */
   1448       if(eState == OMX_StateExecuting)
   1449       {
   1450         DEBUG_PRINT_LOW("\n Pause --> Executing \n");
   1451         if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
   1452                    NULL) < 0)
   1453         {
   1454           DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed");
   1455           post_event(OMX_EventError,OMX_ErrorHardware,\
   1456                      OMX_COMPONENT_GENERATE_EVENT);
   1457           eRet = OMX_ErrorHardware;
   1458         }
   1459         else
   1460         {
   1461           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
   1462           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   1463           post_event (NULL,VDEC_S_SUCCESS,\
   1464                       OMX_COMPONENT_GENERATE_RESUME_DONE);
   1465           bFlag = 0;
   1466         }
   1467       }
   1468       /* Requesting transition from Pause to Idle */
   1469       else if(eState == OMX_StateIdle)
   1470       {
   1471         /* Since error is None , we will post an event
   1472         at the end of this function definition */
   1473         DEBUG_PRINT_LOW("\n Pause --> Idle \n");
   1474          BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   1475          if(!sem_posted)
   1476          {
   1477            sem_posted = 1;
   1478            sem_post (&m_cmd_lock);
   1479            execute_omx_flush(OMX_ALL);
   1480          }
   1481          bFlag = 0;
   1482       }
   1483       /* Requesting transition from Pause to loaded */
   1484       else if(eState == OMX_StateLoaded)
   1485       {
   1486         DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
   1487         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1488                    OMX_COMPONENT_GENERATE_EVENT);
   1489         eRet = OMX_ErrorIncorrectStateTransition;
   1490       }
   1491       /* Requesting transition from Pause to WaitForResources */
   1492       else if(eState == OMX_StateWaitForResources)
   1493       {
   1494         DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
   1495         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1496                    OMX_COMPONENT_GENERATE_EVENT);
   1497         eRet = OMX_ErrorIncorrectStateTransition;
   1498       }
   1499       /* Requesting transition from Pause to Pause */
   1500       else if(eState == OMX_StatePause)
   1501       {
   1502         DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
   1503         post_event(OMX_EventError,OMX_ErrorSameState,\
   1504                    OMX_COMPONENT_GENERATE_EVENT);
   1505         eRet = OMX_ErrorSameState;
   1506       }
   1507        /* Requesting transition from Pause to Invalid */
   1508       else if(eState == OMX_StateInvalid)
   1509       {
   1510         DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
   1511         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1512         eRet = OMX_ErrorInvalidState;
   1513       }
   1514       else
   1515       {
   1516         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
   1517         eRet = OMX_ErrorBadParameter;
   1518       }
   1519     }
   1520      /***************************/
   1521     /* Current State is WaitForResources  */
   1522     /***************************/
   1523     else if(m_state == OMX_StateWaitForResources)
   1524     {
   1525       /* Requesting transition from WaitForResources to Loaded */
   1526       if(eState == OMX_StateLoaded)
   1527       {
   1528         /* Since error is None , we will post an event
   1529         at the end of this function definition */
   1530         DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
   1531       }
   1532       /* Requesting transition from WaitForResources to WaitForResources */
   1533       else if (eState == OMX_StateWaitForResources)
   1534       {
   1535         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
   1536         post_event(OMX_EventError,OMX_ErrorSameState,
   1537                    OMX_COMPONENT_GENERATE_EVENT);
   1538         eRet = OMX_ErrorSameState;
   1539       }
   1540       /* Requesting transition from WaitForResources to Executing */
   1541       else if(eState == OMX_StateExecuting)
   1542       {
   1543         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
   1544         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1545                    OMX_COMPONENT_GENERATE_EVENT);
   1546         eRet = OMX_ErrorIncorrectStateTransition;
   1547       }
   1548       /* Requesting transition from WaitForResources to Pause */
   1549       else if(eState == OMX_StatePause)
   1550       {
   1551         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
   1552         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1553                    OMX_COMPONENT_GENERATE_EVENT);
   1554         eRet = OMX_ErrorIncorrectStateTransition;
   1555       }
   1556       /* Requesting transition from WaitForResources to Invalid */
   1557       else if(eState == OMX_StateInvalid)
   1558       {
   1559         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
   1560         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1561         eRet = OMX_ErrorInvalidState;
   1562       }
   1563       /* Requesting transition from WaitForResources to Loaded -
   1564       is NOT tested by Khronos TS */
   1565 
   1566     }
   1567     else
   1568     {
   1569       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
   1570       eRet = OMX_ErrorBadParameter;
   1571     }
   1572   }
   1573   /********************************/
   1574   /* Current State is Invalid */
   1575   /*******************************/
   1576   else if(m_state == OMX_StateInvalid)
   1577   {
   1578     /* State Transition from Inavlid to any state */
   1579     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
   1580                   || OMX_StateIdle || OMX_StateExecuting
   1581                   || OMX_StatePause || OMX_StateInvalid))
   1582     {
   1583       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
   1584       post_event(OMX_EventError,OMX_ErrorInvalidState,\
   1585                  OMX_COMPONENT_GENERATE_EVENT);
   1586       eRet = OMX_ErrorInvalidState;
   1587     }
   1588   }
   1589   else if (cmd == OMX_CommandFlush)
   1590   {
   1591     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
   1592         "with param1: %d", param1);
   1593     if(0 == param1 || OMX_ALL == param1)
   1594     {
   1595       BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1596     }
   1597     if(1 == param1 || OMX_ALL == param1)
   1598     {
   1599       //generate output flush event only.
   1600       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1601     }
   1602     if (!sem_posted){
   1603       sem_posted = 1;
   1604       DEBUG_PRINT_LOW("\n Set the Semaphore");
   1605       sem_post (&m_cmd_lock);
   1606       execute_omx_flush(param1);
   1607     }
   1608     bFlag = 0;
   1609   }
   1610   else if ( cmd == OMX_CommandPortEnable)
   1611   {
   1612     DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
   1613         "with param1: %d", param1);
   1614     if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
   1615       {
   1616         m_inp_bEnabled = OMX_TRUE;
   1617 
   1618         if( (m_state == OMX_StateLoaded &&
   1619              !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1620             || allocate_input_done())
   1621         {
   1622           post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   1623                      OMX_COMPONENT_GENERATE_EVENT);
   1624         }
   1625         else
   1626         {
   1627           DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   1628           BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   1629           // Skip the event notification
   1630           bFlag = 0;
   1631         }
   1632       }
   1633       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
   1634       {
   1635           DEBUG_PRINT_LOW("\n Enable output Port command recieved");
   1636           m_out_bEnabled = OMX_TRUE;
   1637 
   1638           if( (m_state == OMX_StateLoaded &&
   1639               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   1640               || (allocate_output_done()))
   1641           {
   1642              post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   1643                         OMX_COMPONENT_GENERATE_EVENT);
   1644 
   1645           }
   1646           else
   1647           {
   1648               DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   1649               BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   1650               // Skip the event notification
   1651               bFlag = 0;
   1652           }
   1653       }
   1654   }
   1655   else if (cmd == OMX_CommandPortDisable)
   1656   {
   1657       DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
   1658           "with param1: %d", param1);
   1659       if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
   1660       {
   1661           m_inp_bEnabled = OMX_FALSE;
   1662           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1663               && release_input_done())
   1664           {
   1665              post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   1666                         OMX_COMPONENT_GENERATE_EVENT);
   1667           }
   1668           else
   1669           {
   1670              BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   1671              if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   1672              {
   1673                if(!sem_posted)
   1674                {
   1675                  sem_posted = 1;
   1676                  sem_post (&m_cmd_lock);
   1677                 execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   1678                }
   1679              }
   1680 
   1681              // Skip the event notification
   1682              bFlag = 0;
   1683           }
   1684       }
   1685       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
   1686       {
   1687           m_out_bEnabled = OMX_FALSE;
   1688           DEBUG_PRINT_LOW("\n Disable output Port command recieved");
   1689           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   1690               && release_output_done())
   1691           {
   1692              post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   1693                         OMX_COMPONENT_GENERATE_EVENT);
   1694           }
   1695           else
   1696          {
   1697             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1698             if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   1699             {
   1700               if(!sem_posted)
   1701               {
   1702                 sem_posted = 1;
   1703                 sem_post (&m_cmd_lock);
   1704                 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   1705               }
   1706             }
   1707             // Skip the event notification
   1708             bFlag = 0;
   1709 
   1710          }
   1711       }
   1712   }
   1713   else
   1714   {
   1715     DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
   1716     eRet = OMX_ErrorNotImplemented;
   1717   }
   1718   if(eRet == OMX_ErrorNone && bFlag)
   1719   {
   1720     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   1721   }
   1722   if(!sem_posted)
   1723   {
   1724     sem_post(&m_cmd_lock);
   1725   }
   1726 
   1727   return eRet;
   1728 }
   1729 
   1730 /* ======================================================================
   1731 FUNCTION
   1732   omx_vdec::ExecuteOmxFlush
   1733 
   1734 DESCRIPTION
   1735   Executes the OMX flush.
   1736 
   1737 PARAMETERS
   1738   flushtype - input flush(1)/output flush(0)/ both.
   1739 
   1740 RETURN VALUE
   1741   true/false
   1742 
   1743 ========================================================================== */
   1744 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   1745 {
   1746   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   1747   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_ALL;
   1748   bool bRet = false;
   1749 
   1750   if(flushType == 0 || flushType == OMX_ALL)
   1751   {
   1752     input_flush_progress = true;
   1753     //flush input only
   1754     bRet = execute_input_flush(flushType);
   1755   }
   1756   if(flushType == 1 || flushType == OMX_ALL)
   1757   {
   1758     //flush output only
   1759     output_flush_progress = true;
   1760     bRet = execute_output_flush(flushType);
   1761   }
   1762 
   1763   if(flushType == OMX_ALL)
   1764   {
   1765     /*Check if there are buffers with the Driver*/
   1766     DEBUG_PRINT_LOW("\n Flush ALL ioctl issued");
   1767     ioctl_msg.inputparam = &flush_dir;
   1768     ioctl_msg.outputparam = NULL;
   1769 
   1770     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
   1771     {
   1772       DEBUG_PRINT_ERROR("\n Flush ALL Failed ");
   1773       return false;
   1774     }
   1775   }
   1776 
   1777   return bRet;
   1778 }
   1779 /*=========================================================================
   1780 FUNCTION : execute_output_flush
   1781 
   1782 DESCRIPTION
   1783   Executes the OMX flush at OUTPUT PORT.
   1784 
   1785 PARAMETERS
   1786   None.
   1787 
   1788 RETURN VALUE
   1789   true/false
   1790 ==========================================================================*/
   1791 bool omx_vdec::execute_output_flush(OMX_U32 flushType)
   1792 {
   1793   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   1794   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_OUTPUT;
   1795   unsigned      p1 = 0; // Parameter - 1
   1796   unsigned      p2 = 0; // Parameter - 2
   1797   unsigned      ident = 0;
   1798   bool bRet = true;
   1799 
   1800   /*Generate FBD for all Buffers in the FTBq*/
   1801   pthread_mutex_lock(&m_lock);
   1802   DEBUG_PRINT_LOW("\n Initiate Output Flush");
   1803   while (m_ftb_q.m_size)
   1804   {
   1805     DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
   1806                        m_ftb_q.m_size,pending_output_buffers);
   1807     m_ftb_q.pop_entry(&p1,&p2,&ident);
   1808 
   1809     if(ident == OMX_COMPONENT_GENERATE_FTB )
   1810     {
   1811       DEBUG_PRINT_LOW("\n Inside Flush Buffer OMX_COMPONENT_GENERATE_FTB");
   1812       pending_output_buffers++;
   1813       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1814     }
   1815     else if (ident == OMX_COMPONENT_GENERATE_FBD)
   1816     {
   1817       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1818     }
   1819   }
   1820   pthread_mutex_unlock(&m_lock);
   1821 
   1822   if(gate_output_buffers)
   1823   {
   1824     DEBUG_PRINT_LOW("\n Output Buffers gated Check flush response");
   1825     if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
   1826     {
   1827       DEBUG_PRINT_LOW("\n Notify Output Flush done");
   1828       BITMASK_CLEAR (&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1829       m_cb.EventHandler(&m_cmp,m_app_data,OMX_EventCmdComplete,OMX_CommandFlush,
   1830                                OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   1831     }
   1832     output_flush_progress = false;
   1833     return bRet;
   1834   }
   1835 
   1836   DEBUG_PRINT_LOW("\n output buffers count = %d",pending_output_buffers);
   1837 
   1838   if(flushType == 1)
   1839   {
   1840     /*Check if there are buffers with the Driver*/
   1841     DEBUG_PRINT_LOW("\n ioctl command flush for output");
   1842     ioctl_msg.inputparam = &flush_dir;
   1843     ioctl_msg.outputparam = NULL;
   1844 
   1845     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
   1846     {
   1847       DEBUG_PRINT_ERROR("\n output flush failed");
   1848       return false;
   1849     }
   1850   }
   1851 
   1852   return bRet;
   1853 }
   1854 /*=========================================================================
   1855 FUNCTION : execute_input_flush
   1856 
   1857 DESCRIPTION
   1858   Executes the OMX flush at INPUT PORT.
   1859 
   1860 PARAMETERS
   1861   None.
   1862 
   1863 RETURN VALUE
   1864   true/false
   1865 ==========================================================================*/
   1866 bool omx_vdec::execute_input_flush(OMX_U32 flushType)
   1867 {
   1868   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   1869   enum vdec_bufferflush flush_dir = VDEC_FLUSH_TYPE_INPUT;
   1870   unsigned       i =0;
   1871   unsigned      p1 = 0; // Parameter - 1
   1872   unsigned      p2 = 0; // Parameter - 2
   1873   unsigned      ident = 0;
   1874   bool bRet = true;
   1875 
   1876   /*Generate EBD for all Buffers in the ETBq*/
   1877   DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
   1878 
   1879   pthread_mutex_lock(&m_lock);
   1880   DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
   1881   while (m_etb_q.m_size)
   1882   {
   1883     m_etb_q.pop_entry(&p1,&p2,&ident);
   1884 
   1885     if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
   1886     {
   1887       DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   1888       m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   1889     }
   1890     else if(ident == OMX_COMPONENT_GENERATE_ETB)
   1891     {
   1892       pending_input_buffers++;
   1893       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   1894     }
   1895     else if (ident == OMX_COMPONENT_GENERATE_EBD)
   1896     {
   1897       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   1898     }
   1899   }
   1900 
   1901   /*Check if Heap Buffers are to be flushed*/
   1902   if (arbitrary_bytes)
   1903   {
   1904     DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
   1905     h264_scratch.nFilledLen = 0;
   1906     nal_count = 0;
   1907     look_ahead_nal = false;
   1908     frame_count = 0;
   1909     DEBUG_PRINT_LOW("\n Initialize parser");
   1910     if (m_frame_parser.mutils)
   1911     {
   1912       m_frame_parser.mutils->initialize_frame_checking_environment();
   1913     }
   1914 
   1915     while (m_input_pending_q.m_size)
   1916     {
   1917       m_input_pending_q.pop_entry(&p1,&p2,&ident);
   1918       m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   1919     }
   1920 
   1921     if (psource_frame)
   1922     {
   1923       m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   1924       psource_frame = NULL;
   1925     }
   1926 
   1927     if (pdest_frame)
   1928     {
   1929       pdest_frame->nFilledLen = 0;
   1930       m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
   1931       pdest_frame = NULL;
   1932     }
   1933     m_frame_parser.flush();
   1934   }
   1935 
   1936   pthread_mutex_unlock(&m_lock);
   1937   DEBUG_PRINT_LOW("\n Value of pending input buffers %d \n",pending_input_buffers);
   1938 
   1939   if(flushType == 0)
   1940   {
   1941     /*Check if there are buffers with the Driver*/
   1942     DEBUG_PRINT_LOW("\n Input Flush ioctl issued");
   1943     ioctl_msg.inputparam = &flush_dir;
   1944     ioctl_msg.outputparam = NULL;
   1945 
   1946     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_CMD_FLUSH,&ioctl_msg) < 0)
   1947     {
   1948       DEBUG_PRINT_ERROR("\n Input Flush Failed ");
   1949       return false;
   1950     }
   1951   }
   1952 
   1953   return bRet;
   1954 }
   1955 
   1956 
   1957 /* ======================================================================
   1958 FUNCTION
   1959   omx_vdec::SendCommandEvent
   1960 
   1961 DESCRIPTION
   1962   Send the event to decoder pipe.  This is needed to generate the callbacks
   1963   in decoder thread context.
   1964 
   1965 PARAMETERS
   1966   None.
   1967 
   1968 RETURN VALUE
   1969   true/false
   1970 
   1971 ========================================================================== */
   1972 bool omx_vdec::post_event(unsigned int p1,
   1973                           unsigned int p2,
   1974                           unsigned int id)
   1975 {
   1976   bool bRet      =                      false;
   1977 
   1978 
   1979   pthread_mutex_lock(&m_lock);
   1980 
   1981   if( id == OMX_COMPONENT_GENERATE_FTB || \
   1982       (id == OMX_COMPONENT_GENERATE_FBD)||
   1983       (id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH))
   1984   {
   1985     m_ftb_q.insert_entry(p1,p2,id);
   1986   }
   1987   else if((id == OMX_COMPONENT_GENERATE_ETB) \
   1988           || (id == OMX_COMPONENT_GENERATE_EBD)||
   1989           (id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)||
   1990           (id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH))
   1991   {
   1992     m_etb_q.insert_entry(p1,p2,id);
   1993   }
   1994   else
   1995   {
   1996     m_cmd_q.insert_entry(p1,p2,id);
   1997   }
   1998 
   1999   bRet = true;
   2000   DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
   2001   post_message(this, id);
   2002 
   2003   pthread_mutex_unlock(&m_lock);
   2004 
   2005   return bRet;
   2006 }
   2007 
   2008 /* ======================================================================
   2009 FUNCTION
   2010   omx_vdec::GetParameter
   2011 
   2012 DESCRIPTION
   2013   OMX Get Parameter method implementation
   2014 
   2015 PARAMETERS
   2016   <TBD>.
   2017 
   2018 RETURN VALUE
   2019   Error None if successful.
   2020 
   2021 ========================================================================== */
   2022 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2023                                            OMX_IN OMX_INDEXTYPE paramIndex,
   2024                                            OMX_INOUT OMX_PTR     paramData)
   2025 {
   2026     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2027     unsigned int height=0,width = 0;
   2028 
   2029     DEBUG_PRINT_LOW("get_parameter: \n");
   2030     if(m_state == OMX_StateInvalid)
   2031     {
   2032         DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
   2033         return OMX_ErrorInvalidState;
   2034     }
   2035     if(paramData == NULL)
   2036     {
   2037         DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
   2038         return OMX_ErrorBadParameter;
   2039     }
   2040   switch(paramIndex)
   2041   {
   2042     case OMX_IndexParamPortDefinition:
   2043     {
   2044       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   2045       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2046 
   2047       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
   2048 
   2049         portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   2050         portDefn->nSize = sizeof(portDefn);
   2051         portDefn->eDomain    = OMX_PortDomainVideo;
   2052         portDefn->format.video.nFrameHeight =  m_crop_dy;
   2053         portDefn->format.video.nFrameWidth  =  m_crop_dx;
   2054         portDefn->format.video.nStride = m_width;
   2055         portDefn->format.video.nSliceHeight = m_height;
   2056         portDefn->format.video.xFramerate= 25;
   2057 
   2058       if (0 == portDefn->nPortIndex)
   2059       {
   2060         portDefn->eDir =  OMX_DirInput;
   2061         /*Actual count is based on input buffer count*/
   2062         portDefn->nBufferCountActual = m_inp_buf_count;
   2063         /*Set the Min count*/
   2064         portDefn->nBufferCountMin    = m_inp_buf_count_min;
   2065         portDefn->nBufferSize        = m_inp_buf_size;
   2066         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   2067         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   2068         portDefn->bEnabled   = m_inp_bEnabled;
   2069         portDefn->bPopulated = m_inp_bPopulated;
   2070       }
   2071       else if (1 == portDefn->nPortIndex)
   2072       {
   2073         m_out_buf_count = m_out_buf_count_recon;
   2074         m_out_buf_count_min = m_out_buf_count_min_recon;
   2075         m_out_buf_size = m_out_buf_size_recon;
   2076         portDefn->eDir =  OMX_DirOutput;
   2077         portDefn->nBufferCountActual = m_out_buf_count;
   2078         portDefn->nBufferCountMin    = m_out_buf_count_min;
   2079         portDefn->nBufferSize = m_out_buf_size;
   2080         portDefn->bEnabled   = m_out_bEnabled;
   2081         portDefn->bPopulated = m_out_bPopulated;
   2082         height = driver_context.video_resoultion.frame_height;
   2083         width = driver_context.video_resoultion.frame_width;
   2084 
   2085         portDefn->format.video.nFrameHeight =  height;
   2086         portDefn->format.video.nFrameWidth  =  width;
   2087         portDefn->format.video.nStride      = stride;
   2088         portDefn->format.video.nSliceHeight = scan_lines;
   2089         DEBUG_PRINT_LOW("\n Get Param Slice Height %d Slice Width %d",
   2090                            scan_lines,stride);
   2091         //TODO: Need to add color format
   2092         portDefn->format.video.eColorFormat = m_color_format;
   2093         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   2094         DEBUG_PRINT_LOW("\n Output Actual %d Output Min %d",
   2095                            portDefn->nBufferCountActual,portDefn->nBufferCountMin);
   2096       }
   2097       else
   2098       {
   2099         portDefn->eDir =  OMX_DirMax;
   2100         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   2101                  (int)portDefn->nPortIndex);
   2102         eRet = OMX_ErrorBadPortIndex;
   2103       }
   2104 
   2105       break;
   2106     }
   2107     case OMX_IndexParamVideoInit:
   2108     {
   2109       OMX_PORT_PARAM_TYPE *portParamType =
   2110                               (OMX_PORT_PARAM_TYPE *) paramData;
   2111       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
   2112 
   2113       portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2114       portParamType->nSize = sizeof(portParamType);
   2115       portParamType->nPorts           = 2;
   2116       portParamType->nStartPortNumber = 0;
   2117       break;
   2118     }
   2119     case OMX_IndexParamVideoPortFormat:
   2120     {
   2121       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2122                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   2123       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
   2124 
   2125       portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   2126       portFmt->nSize             = sizeof(portFmt);
   2127 
   2128       if (0 == portFmt->nPortIndex)
   2129       {
   2130         if (0 == portFmt->nIndex)
   2131         {
   2132               portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   2133               portFmt->eCompressionFormat = eCompressionFormat;
   2134         }
   2135         else
   2136         {
   2137           DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2138               " NoMore compression formats\n");
   2139           eRet =  OMX_ErrorNoMore;
   2140         }
   2141       }
   2142       else if (1 == portFmt->nPortIndex)
   2143       {
   2144         if (0 == portFmt->nIndex)
   2145         {
   2146            if (driver_context.output_format == VDEC_YUV_FORMAT_NV12)
   2147              portFmt->eColorFormat = OMX_COLOR_FormatYUV420SemiPlanar;
   2148            else
   2149             portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)0x7F000000;
   2150 
   2151            portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   2152         }
   2153         else
   2154         {
   2155            DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2156                   " NoMore Color formats\n");
   2157            eRet =  OMX_ErrorNoMore;
   2158         }
   2159       }
   2160       else
   2161       {
   2162         DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
   2163                           (int)portFmt->nPortIndex);
   2164         eRet = OMX_ErrorBadPortIndex;
   2165       }
   2166       break;
   2167     }
   2168     /*Component should support this port definition*/
   2169     case OMX_IndexParamAudioInit:
   2170     {
   2171         OMX_PORT_PARAM_TYPE *audioPortParamType =
   2172                                               (OMX_PORT_PARAM_TYPE *) paramData;
   2173         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
   2174         audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2175         audioPortParamType->nSize = sizeof(audioPortParamType);
   2176         audioPortParamType->nPorts           = 0;
   2177         audioPortParamType->nStartPortNumber = 0;
   2178         break;
   2179     }
   2180     /*Component should support this port definition*/
   2181     case OMX_IndexParamImageInit:
   2182     {
   2183         OMX_PORT_PARAM_TYPE *imagePortParamType =
   2184                                               (OMX_PORT_PARAM_TYPE *) paramData;
   2185         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
   2186         imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2187         imagePortParamType->nSize = sizeof(imagePortParamType);
   2188         imagePortParamType->nPorts           = 0;
   2189         imagePortParamType->nStartPortNumber = 0;
   2190         break;
   2191 
   2192     }
   2193     /*Component should support this port definition*/
   2194     case OMX_IndexParamOtherInit:
   2195     {
   2196         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
   2197                           paramIndex);
   2198         eRet =OMX_ErrorUnsupportedIndex;
   2199         break;
   2200     }
   2201     case OMX_IndexParamStandardComponentRole:
   2202     {
   2203         OMX_PARAM_COMPONENTROLETYPE *comp_role;
   2204         comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   2205         comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   2206         comp_role->nSize = sizeof(*comp_role);
   2207 
   2208         DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
   2209                     paramIndex);
   2210         strncpy((char*)comp_role->cRole,(const char*)m_cRole,
   2211                     OMX_MAX_STRINGNAME_SIZE);
   2212         break;
   2213     }
   2214     /* Added for parameter test */
   2215     case OMX_IndexParamPriorityMgmt:
   2216         {
   2217 
   2218             OMX_PRIORITYMGMTTYPE *priorityMgmType =
   2219                                              (OMX_PRIORITYMGMTTYPE *) paramData;
   2220             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
   2221             priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   2222             priorityMgmType->nSize = sizeof(priorityMgmType);
   2223 
   2224             break;
   2225         }
   2226     /* Added for parameter test */
   2227     case OMX_IndexParamCompBufferSupplier:
   2228         {
   2229             OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   2230                                      (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   2231             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
   2232 
   2233             bufferSupplierType->nSize = sizeof(bufferSupplierType);
   2234             bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   2235             if(0 == bufferSupplierType->nPortIndex)
   2236                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2237             else if (1 == bufferSupplierType->nPortIndex)
   2238                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2239             else
   2240                 eRet = OMX_ErrorBadPortIndex;
   2241 
   2242 
   2243             break;
   2244         }
   2245     case OMX_IndexParamVideoAvc:
   2246         {
   2247             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
   2248                         paramIndex);
   2249             break;
   2250         }
   2251     case OMX_IndexParamVideoH263:
   2252         {
   2253             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
   2254                         paramIndex);
   2255             break;
   2256         }
   2257     case OMX_IndexParamVideoMpeg4:
   2258         {
   2259             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
   2260                         paramIndex);
   2261             break;
   2262         }
   2263     default:
   2264     {
   2265       DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
   2266       eRet =OMX_ErrorUnsupportedIndex;
   2267     }
   2268 
   2269   }
   2270 
   2271   DEBUG_PRINT_LOW("\n get_parameter returning Height %d , Width %d \n",
   2272               m_height, m_width);
   2273   return eRet;
   2274 
   2275 }
   2276 
   2277 /* ======================================================================
   2278 FUNCTION
   2279   omx_vdec::Setparameter
   2280 
   2281 DESCRIPTION
   2282   OMX Set Parameter method implementation.
   2283 
   2284 PARAMETERS
   2285   <TBD>.
   2286 
   2287 RETURN VALUE
   2288   OMX Error None if successful.
   2289 
   2290 ========================================================================== */
   2291 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2292                                            OMX_IN OMX_INDEXTYPE paramIndex,
   2293                                            OMX_IN OMX_PTR        paramData)
   2294 {
   2295     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2296     struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   2297     unsigned int   alignment = 0,buffer_size = 0;
   2298     int           i;
   2299 
   2300     if(m_state == OMX_StateInvalid)
   2301     {
   2302         DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
   2303         return OMX_ErrorInvalidState;
   2304     }
   2305     if(paramData == NULL)
   2306     {
   2307          DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
   2308          return OMX_ErrorBadParameter;
   2309     }
   2310   switch(paramIndex)
   2311   {
   2312     case OMX_IndexParamPortDefinition:
   2313     {
   2314       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   2315       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2316 
   2317       /*set_parameter can be called in loaded state
   2318       or disabled port */
   2319 
   2320       /* When the component is in Loaded state and IDLE Pending*/
   2321       if(((m_state == OMX_StateLoaded)&&
   2322           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2323          /* Or while the I/P or the O/P port or disabled */
   2324          ||((OMX_DirInput == portDefn->eDir && m_inp_bEnabled == OMX_FALSE)||
   2325          (OMX_DirOutput == portDefn->eDir && m_out_bEnabled == OMX_FALSE)))
   2326       {
   2327        DEBUG_PRINT_LOW("Set Parameter called in valid state");
   2328       }
   2329       else
   2330       {
   2331          DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   2332          return OMX_ErrorIncorrectStateOperation;
   2333       }
   2334       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
   2335              (int)portDefn->format.video.nFrameHeight,
   2336              (int)portDefn->format.video.nFrameWidth);
   2337 
   2338       eRet = omx_vdec_validate_port_param(portDefn->format.video.nFrameHeight,
   2339                                           portDefn->format.video.nFrameWidth);
   2340       if(eRet != OMX_ErrorNone)
   2341       {
   2342          return OMX_ErrorUnsupportedSetting;
   2343       }
   2344       if(OMX_DirOutput == portDefn->eDir)
   2345       {
   2346           if ( portDefn->nBufferCountActual < m_out_buf_count_min ||
   2347                portDefn->nBufferSize !=  m_out_buf_size
   2348               )
   2349           {
   2350               return OMX_ErrorBadParameter;
   2351           }
   2352           driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2353           ioctl_msg.inputparam = NULL;
   2354           ioctl_msg.outputparam = &driver_context.output_buffer;
   2355 
   2356           if (ioctl (driver_context.video_driver_fd,
   2357                      VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
   2358           {
   2359               DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
   2360               return OMX_ErrorUnsupportedSetting;
   2361           }
   2362           driver_context.output_buffer.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2363           driver_context.output_buffer.actualcount =
   2364                                                 portDefn->nBufferCountActual;
   2365           ioctl_msg.inputparam = &driver_context.output_buffer;
   2366           ioctl_msg.outputparam = NULL;
   2367 
   2368           if (ioctl (driver_context.video_driver_fd,
   2369                      VDEC_IOCTL_SET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
   2370           {
   2371               DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
   2372               return OMX_ErrorUnsupportedSetting;
   2373           }
   2374           m_out_buf_count = portDefn->nBufferCountActual;
   2375           m_out_buf_count_recon = m_out_buf_count;
   2376         DEBUG_PRINT_LOW("set_parameter:OMX_IndexParamPortDefinition output port\n");
   2377       }
   2378       else if(OMX_DirInput == portDefn->eDir)
   2379       {
   2380          if(m_height != portDefn->format.video.nFrameHeight ||
   2381             m_width  != portDefn->format.video.nFrameWidth)
   2382          {
   2383            DEBUG_PRINT_LOW("set_parameter ip port: stride %d\n",
   2384                        (int)portDefn->format.video.nStride);
   2385            // set the HxW only if non-zero
   2386            if((portDefn->format.video.nFrameHeight != 0x0)
   2387               && (portDefn->format.video.nFrameWidth != 0x0))
   2388            {
   2389                m_crop_x = m_crop_y = 0;
   2390                m_crop_dy = m_port_height = m_height =
   2391                  portDefn->format.video.nFrameHeight;
   2392                m_crop_dx = m_port_width = m_width  =
   2393                  portDefn->format.video.nFrameWidth;
   2394                scan_lines = portDefn->format.video.nSliceHeight;
   2395                stride = portDefn->format.video.nStride;
   2396                DEBUG_PRINT_LOW("\n SetParam with new H %d and W %d\n",
   2397                            m_height, m_width );
   2398                driver_context.video_resoultion.frame_height = m_height;
   2399                driver_context.video_resoultion.frame_width = m_width;
   2400                driver_context.video_resoultion.stride = stride;
   2401                driver_context.video_resoultion.scan_lines = scan_lines;
   2402                ioctl_msg.inputparam = &driver_context.video_resoultion;
   2403                ioctl_msg.outputparam = NULL;
   2404 
   2405                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_PICRES,
   2406                           (void*)&ioctl_msg) < 0)
   2407                {
   2408                    DEBUG_PRINT_ERROR("\n Set Resolution failed");
   2409                    return OMX_ErrorUnsupportedSetting;
   2410                }
   2411                driver_context.output_buffer.buffer_type =
   2412                                                         VDEC_BUFFER_TYPE_OUTPUT;
   2413                ioctl_msg.inputparam = NULL;
   2414                ioctl_msg.outputparam = &driver_context.output_buffer;
   2415 
   2416                if (ioctl (driver_context.video_driver_fd,
   2417                           VDEC_IOCTL_GET_BUFFER_REQ,(void*)&ioctl_msg) < 0)
   2418                {
   2419                    DEBUG_PRINT_ERROR("\n Request output buffer requirements failed");
   2420                    return OMX_ErrorUnsupportedSetting;
   2421                }
   2422 
   2423                m_out_buf_count_recon = m_out_buf_count = driver_context.output_buffer.actualcount;
   2424                m_out_buf_count_min_recon = m_out_buf_count_min = driver_context.output_buffer.mincount;
   2425 
   2426                alignment = driver_context.output_buffer.alignment;
   2427                buffer_size = driver_context.output_buffer.buffer_size;
   2428                m_out_buf_size_recon = m_out_buf_size =
   2429                  ((buffer_size + alignment - 1) & (~(alignment - 1)));
   2430            }
   2431         }
   2432         else
   2433         {
   2434             /*
   2435               If actual buffer count is greater than the Min buffer
   2436               count,change the actual count.
   2437               m_inp_buf_count is initialized to OMX_CORE_NUM_INPUT_BUFFERS
   2438               in the constructor
   2439             */
   2440             if ( portDefn->nBufferCountActual < m_inp_buf_count_min ||
   2441                  portDefn->nBufferSize !=  m_inp_buf_size
   2442                 )
   2443             {
   2444                 return OMX_ErrorBadParameter;
   2445             }
   2446                /*Get the Buffer requirements for input and output ports*/
   2447                driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2448                ioctl_msg.inputparam = NULL;
   2449                ioctl_msg.outputparam = &driver_context.input_buffer;
   2450 
   2451                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
   2452                           (void*)&ioctl_msg) < 0)
   2453                {
   2454                    DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
   2455                    return OMX_ErrorUnsupportedSetting;
   2456                }
   2457 
   2458                driver_context.input_buffer.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2459                driver_context.input_buffer.actualcount =
   2460                  portDefn->nBufferCountActual;
   2461                ioctl_msg.inputparam = &driver_context.input_buffer;
   2462                ioctl_msg.outputparam = NULL;
   2463 
   2464                if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
   2465                           (void*)&ioctl_msg) < 0)
   2466                {
   2467                    DEBUG_PRINT_ERROR("\n Request input buffer requirements failed");
   2468                    return OMX_ErrorUnsupportedSetting;
   2469                }
   2470 
   2471             m_inp_buf_count = portDefn->nBufferCountActual;
   2472           DEBUG_PRINT_LOW("\n set_parameter: Image Dimensions same  \n");
   2473         }
   2474 
   2475       }
   2476       else if (portDefn->eDir ==  OMX_DirMax)
   2477       {
   2478           DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   2479                       (int)portDefn->nPortIndex);
   2480           eRet = OMX_ErrorBadPortIndex;
   2481       }
   2482     }
   2483     break;
   2484 
   2485 
   2486     case OMX_IndexParamVideoPortFormat:
   2487     {
   2488       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2489                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   2490       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
   2491               portFmt->eColorFormat);
   2492 
   2493       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
   2494              portFmt->eColorFormat);
   2495       if(1 == portFmt->nPortIndex)
   2496       {
   2497 
   2498          m_color_format = portFmt->eColorFormat;
   2499       }
   2500     }
   2501     break;
   2502 
   2503     case OMX_QcomIndexPortDefn:
   2504     {
   2505         OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   2506             (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   2507         DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d\n",
   2508             portFmt->nFramePackingFormat);
   2509 
   2510         /* Input port */
   2511         if (portFmt->nPortIndex == 0)
   2512         {
   2513             if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary)
   2514             {
   2515                arbitrary_bytes = true;
   2516             }
   2517             else if (portFmt->nFramePackingFormat ==
   2518                 OMX_QCOM_FramePacking_OnlyOneCompleteFrame)
   2519             {
   2520                arbitrary_bytes = false;
   2521             }
   2522             else
   2523             {
   2524                 DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
   2525                     portFmt->nFramePackingFormat);
   2526                 eRet = OMX_ErrorUnsupportedSetting;
   2527             }
   2528         }
   2529     }
   2530     break;
   2531 
   2532      case OMX_IndexParamStandardComponentRole:
   2533      {
   2534           OMX_PARAM_COMPONENTROLETYPE *comp_role;
   2535           comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   2536           DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
   2537                        comp_role->cRole);
   2538 
   2539           if((m_state == OMX_StateLoaded)&&
   2540               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2541           {
   2542            DEBUG_PRINT_LOW("Set Parameter called in valid state");
   2543           }
   2544           else
   2545           {
   2546              DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   2547              return OMX_ErrorIncorrectStateOperation;
   2548           }
   2549 
   2550           if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
   2551           {
   2552               if(!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE))
   2553               {
   2554                   strncpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   2555               }
   2556               else
   2557               {
   2558                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   2559                   eRet =OMX_ErrorUnsupportedSetting;
   2560               }
   2561           }
   2562           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
   2563           {
   2564               if(!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
   2565               {
   2566                   strncpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   2567               }
   2568               else
   2569               {
   2570                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   2571                   eRet = OMX_ErrorUnsupportedSetting;
   2572               }
   2573           }
   2574           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
   2575           {
   2576               if(!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE))
   2577               {
   2578                   strncpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   2579               }
   2580               else
   2581               {
   2582                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   2583                   eRet =OMX_ErrorUnsupportedSetting;
   2584               }
   2585           }
   2586           else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
   2587           {
   2588               if(!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
   2589               {
   2590                   strncpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2591               }
   2592               else
   2593               {
   2594                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   2595                   eRet =OMX_ErrorUnsupportedSetting;
   2596               }
   2597           }
   2598           else
   2599           {
   2600                DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", driver_context.kind);
   2601                eRet = OMX_ErrorInvalidComponentName;
   2602           }
   2603           break;
   2604      }
   2605 
   2606     case OMX_IndexParamPriorityMgmt:
   2607         {
   2608             if(m_state != OMX_StateLoaded)
   2609             {
   2610                DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   2611                return OMX_ErrorIncorrectStateOperation;
   2612             }
   2613             OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   2614             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
   2615               priorityMgmtype->nGroupID);
   2616 
   2617             DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
   2618              priorityMgmtype->nGroupPriority);
   2619 
   2620             m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   2621             m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   2622 
   2623             break;
   2624         }
   2625 
   2626       case OMX_IndexParamCompBufferSupplier:
   2627       {
   2628           OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   2629             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
   2630                 bufferSupplierType->eBufferSupplier);
   2631              if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   2632                 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   2633 
   2634              else
   2635 
   2636              eRet = OMX_ErrorBadPortIndex;
   2637 
   2638           break;
   2639 
   2640       }
   2641       case OMX_IndexParamVideoAvc:
   2642           {
   2643               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
   2644                     paramIndex);
   2645               break;
   2646           }
   2647       case OMX_IndexParamVideoH263:
   2648           {
   2649               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
   2650                     paramIndex);
   2651               break;
   2652           }
   2653       case OMX_IndexParamVideoMpeg4:
   2654           {
   2655               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
   2656                     paramIndex);
   2657               break;
   2658           }
   2659 
   2660     default:
   2661     {
   2662       DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
   2663       eRet = OMX_ErrorUnsupportedIndex;
   2664     }
   2665   }
   2666 
   2667   return eRet;
   2668 }
   2669 
   2670 /* ======================================================================
   2671 FUNCTION
   2672   omx_vdec::GetConfig
   2673 
   2674 DESCRIPTION
   2675   OMX Get Config Method implementation.
   2676 
   2677 PARAMETERS
   2678   <TBD>.
   2679 
   2680 RETURN VALUE
   2681   OMX Error None if successful.
   2682 
   2683 ========================================================================== */
   2684 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   2685                                         OMX_IN OMX_INDEXTYPE configIndex,
   2686                                         OMX_INOUT OMX_PTR     configData)
   2687 {
   2688   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2689 
   2690   if (m_state == OMX_StateInvalid)
   2691   {
   2692      DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   2693      return OMX_ErrorInvalidState;
   2694   }
   2695 
   2696   switch (configIndex)
   2697   {
   2698     case OMX_QcomIndexConfigInterlaced:
   2699     {
   2700       OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   2701                                    (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   2702       if (configFmt->nPortIndex == 1)
   2703       {
   2704         if (configFmt->nIndex == 0)
   2705         {
   2706           configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   2707         }
   2708         else if (configFmt->nIndex == 1)
   2709         {
   2710           configFmt->eInterlaceType =
   2711                                   OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   2712         }
   2713         else if (configFmt->nIndex == 2)
   2714         {
   2715           configFmt->eInterlaceType =
   2716           OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   2717         }
   2718         else
   2719         {
   2720           DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   2721                             " NoMore Interlaced formats\n");
   2722           eRet = OMX_ErrorNoMore;
   2723         }
   2724 
   2725       }
   2726       else
   2727       {
   2728         DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
   2729         (int)configFmt->nPortIndex);
   2730         eRet = OMX_ErrorBadPortIndex;
   2731       }
   2732     break;
   2733     }
   2734     case OMX_QcomIndexQueryNumberOfVideoDecInstance:
   2735     {
   2736         struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   2737         QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   2738           (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   2739         ioctl_msg.outputparam = (void*)&decoderinstances->nNumOfInstances;
   2740         (void)(ioctl(driver_context.video_driver_fd,
   2741                VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
   2742     break;
   2743     }
   2744     default:
   2745     {
   2746       DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
   2747       eRet = OMX_ErrorBadParameter;
   2748     }
   2749 
   2750   }
   2751 
   2752   return eRet;
   2753 }
   2754 
   2755 /* ======================================================================
   2756 FUNCTION
   2757   omx_vdec::SetConfig
   2758 
   2759 DESCRIPTION
   2760   OMX Set Config method implementation
   2761 
   2762 PARAMETERS
   2763   <TBD>.
   2764 
   2765 RETURN VALUE
   2766   OMX Error None if successful.
   2767 ========================================================================== */
   2768 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   2769                                         OMX_IN OMX_INDEXTYPE configIndex,
   2770                                         OMX_IN OMX_PTR        configData)
   2771 {
   2772   if(m_state == OMX_StateInvalid)
   2773   {
   2774       DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   2775       return OMX_ErrorInvalidState;
   2776   }
   2777 
   2778   OMX_ERRORTYPE ret = OMX_ErrorNone;
   2779   OMX_VIDEO_CONFIG_NALSIZE *pNal;
   2780 
   2781   DEBUG_PRINT_LOW("\n Set Config Called");
   2782 
   2783   if (m_state == OMX_StateExecuting)
   2784   {
   2785      DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
   2786      return ret;
   2787   }
   2788 
   2789   if (configIndex == OMX_IndexVendorVideoExtraData)
   2790   {
   2791     OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
   2792     DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
   2793     if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.avc"))
   2794     {
   2795       DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
   2796       OMX_U32 extra_size;
   2797       // Parsing done here for the AVC atom is definitely not generic
   2798       // Currently this piece of code is working, but certainly
   2799       // not tested with all .mp4 files.
   2800       // Incase of failure, we might need to revisit this
   2801       // for a generic piece of code.
   2802 
   2803       // Retrieve size of NAL length field
   2804       // byte #4 contains the size of NAL lenght field
   2805       nal_length = (config->pData[4] & 0x03) + 1;
   2806 
   2807       extra_size = 0;
   2808       if (nal_length > 2)
   2809       {
   2810         /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
   2811         extra_size = (nal_length - 2) * 2;
   2812       }
   2813 
   2814       // SPS starts from byte #6
   2815       OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
   2816       OMX_U8 *pDestBuf;
   2817       m_vendor_config.nPortIndex = config->nPortIndex;
   2818 
   2819       // minus 6 --> SPS starts from byte #6
   2820       // minus 1 --> picture param set byte to be ignored from avcatom
   2821       m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
   2822       m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
   2823       OMX_U32 len;
   2824       OMX_U8 index = 0;
   2825       // case where SPS+PPS is sent as part of set_config
   2826       pDestBuf = m_vendor_config.pData;
   2827 
   2828       DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]\n",
   2829            m_vendor_config.nPortIndex,
   2830            m_vendor_config.nDataSize,
   2831            m_vendor_config.pData);
   2832       while (index < 2)
   2833       {
   2834         uint8 *psize;
   2835         len = *pSrcBuf;
   2836         len = len << 8;
   2837         len |= *(pSrcBuf + 1);
   2838         psize = (uint8 *) & len;
   2839         memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
   2840         for (int i = 0; i < nal_length; i++)
   2841         {
   2842           pDestBuf[i] = psize[nal_length - 1 - i];
   2843         }
   2844         //memcpy(pDestBuf,pSrcBuf,(len+2));
   2845         pDestBuf += len + nal_length;
   2846         pSrcBuf += len + 2;
   2847         index++;
   2848         pSrcBuf++;   // skip picture param set
   2849         len = 0;
   2850       }
   2851     }
   2852     else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4"))
   2853     {
   2854       m_vendor_config.nPortIndex = config->nPortIndex;
   2855       m_vendor_config.nDataSize = config->nDataSize;
   2856       m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
   2857       memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
   2858     }
   2859     else if (!strcmp(driver_context.kind, "OMX.qcom.video.decoder.vc1"))
   2860     {
   2861         if(m_vendor_config.pData)
   2862         {
   2863             free(m_vendor_config.pData);
   2864             m_vendor_config.pData = NULL;
   2865             m_vendor_config.nDataSize = 0;
   2866         }
   2867 
   2868         if (((*((OMX_U32 *) config->pData)) &
   2869              VC1_SP_MP_START_CODE_MASK) ==
   2870              VC1_SP_MP_START_CODE)
   2871         {
   2872             DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
   2873             m_vendor_config.nPortIndex = config->nPortIndex;
   2874             m_vendor_config.nDataSize = config->nDataSize;
   2875             m_vendor_config.pData =
   2876                 (OMX_U8 *) malloc(config->nDataSize);
   2877             memcpy(m_vendor_config.pData, config->pData,
   2878                    config->nDataSize);
   2879             m_vc1_profile = VC1_SP_MP_RCV;
   2880         }
   2881         else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE)
   2882         {
   2883             DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
   2884             m_vendor_config.nPortIndex = config->nPortIndex;
   2885             m_vendor_config.nDataSize = config->nDataSize;
   2886             m_vendor_config.pData =
   2887                 (OMX_U8 *) malloc((config->nDataSize));
   2888             memcpy(m_vendor_config.pData, config->pData,
   2889                    config->nDataSize);
   2890             m_vc1_profile = VC1_AP;
   2891         }
   2892         else if ((config->nDataSize == VC1_STRUCT_C_LEN))
   2893         {
   2894             DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
   2895             m_vendor_config.nPortIndex = config->nPortIndex;
   2896             m_vendor_config.nDataSize  = config->nDataSize;
   2897             m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
   2898             memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
   2899             m_vc1_profile = VC1_SP_MP_RCV;
   2900         }
   2901         else
   2902         {
   2903             DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
   2904         }
   2905     }
   2906     return ret;
   2907   }
   2908   else if (configIndex == OMX_IndexConfigVideoNalSize)
   2909   {
   2910 
   2911     pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   2912     nal_length = pNal->nNaluBytes;
   2913     m_frame_parser.init_nal_length(nal_length);
   2914     DEBUG_PRINT_LOW("\n Nal Length option called with Size %d",nal_length);
   2915     return ret;
   2916   }
   2917 
   2918   return OMX_ErrorNotImplemented;
   2919 }
   2920 
   2921 /* ======================================================================
   2922 FUNCTION
   2923   omx_vdec::GetExtensionIndex
   2924 
   2925 DESCRIPTION
   2926   OMX GetExtensionIndex method implementaion.  <TBD>
   2927 
   2928 PARAMETERS
   2929   <TBD>.
   2930 
   2931 RETURN VALUE
   2932   OMX Error None if everything successful.
   2933 
   2934 ========================================================================== */
   2935 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   2936                                                 OMX_IN OMX_STRING      paramName,
   2937                                                 OMX_OUT OMX_INDEXTYPE* indexType)
   2938 {
   2939     DEBUG_PRINT_ERROR("get_extension_index: Error, Not implemented\n");
   2940     if(m_state == OMX_StateInvalid)
   2941     {
   2942         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
   2943         return OMX_ErrorInvalidState;
   2944     }
   2945     return OMX_ErrorNotImplemented;
   2946 }
   2947 
   2948 /* ======================================================================
   2949 FUNCTION
   2950   omx_vdec::GetState
   2951 
   2952 DESCRIPTION
   2953   Returns the state information back to the caller.<TBD>
   2954 
   2955 PARAMETERS
   2956   <TBD>.
   2957 
   2958 RETURN VALUE
   2959   Error None if everything is successful.
   2960 ========================================================================== */
   2961 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   2962                                        OMX_OUT OMX_STATETYPE* state)
   2963 {
   2964   *state = m_state;
   2965   DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
   2966   return OMX_ErrorNone;
   2967 }
   2968 
   2969 /* ======================================================================
   2970 FUNCTION
   2971   omx_vdec::ComponentTunnelRequest
   2972 
   2973 DESCRIPTION
   2974   OMX Component Tunnel Request method implementation. <TBD>
   2975 
   2976 PARAMETERS
   2977   None.
   2978 
   2979 RETURN VALUE
   2980   OMX Error None if everything successful.
   2981 
   2982 ========================================================================== */
   2983 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
   2984                                                      OMX_IN OMX_U32                        port,
   2985                                                      OMX_IN OMX_HANDLETYPE        peerComponent,
   2986                                                      OMX_IN OMX_U32                    peerPort,
   2987                                                      OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   2988 {
   2989   DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
   2990   return OMX_ErrorNotImplemented;
   2991 }
   2992 
   2993 /* ======================================================================
   2994 FUNCTION
   2995   omx_vdec::UseInputBuffer
   2996 
   2997 DESCRIPTION
   2998   Helper function for Use buffer in the input pin
   2999 
   3000 PARAMETERS
   3001   None.
   3002 
   3003 RETURN VALUE
   3004   true/false
   3005 
   3006 ========================================================================== */
   3007 OMX_ERRORTYPE  omx_vdec::use_input_buffer(
   3008                          OMX_IN OMX_HANDLETYPE            hComp,
   3009                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3010                          OMX_IN OMX_U32                   port,
   3011                          OMX_IN OMX_PTR                   appData,
   3012                          OMX_IN OMX_U32                   bytes,
   3013                          OMX_IN OMX_U8*                   buffer)
   3014 {
   3015   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3016   struct vdec_setbuffer_cmd setbuffers;
   3017   OMX_BUFFERHEADERTYPE *input = NULL;
   3018   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   3019   unsigned   i = 0;
   3020   unsigned char *buf_addr = NULL;
   3021   int pmem_fd = -1;
   3022 
   3023   if(bytes != m_inp_buf_size)
   3024   {
   3025     return OMX_ErrorBadParameter;
   3026   }
   3027 
   3028   if(!m_inp_mem_ptr)
   3029   {
   3030     DEBUG_PRINT_HIGH("\n Use i/p buffer case - Header List allocation");
   3031     input_use_buffer = true;
   3032     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   3033     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
   3034 
   3035     if (m_inp_mem_ptr == NULL)
   3036     {
   3037       return OMX_ErrorInsufficientResources;
   3038     }
   3039 
   3040     driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   3041     calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
   3042 
   3043     if (driver_context.ptr_inputbuffer == NULL)
   3044     {
   3045       return OMX_ErrorInsufficientResources;
   3046     }
   3047 
   3048     for (i=0; i < m_inp_buf_count; i++)
   3049     {
   3050       driver_context.ptr_inputbuffer [i].pmem_fd = -1;
   3051     }
   3052   }
   3053 
   3054   for(i=0; i< m_inp_buf_count; i++)
   3055   {
   3056     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   3057     {
   3058       break;
   3059     }
   3060   }
   3061 
   3062   if(i < m_inp_buf_count)
   3063   {
   3064     pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
   3065 
   3066     if (pmem_fd < 0)
   3067     {
   3068       return OMX_ErrorInsufficientResources;
   3069     }
   3070 
   3071     if(pmem_fd == 0)
   3072     {
   3073       pmem_fd = open ("/dev/pmem_adsp",O_RDWR | O_SYNC);
   3074       if (pmem_fd < 0)
   3075       {
   3076         return OMX_ErrorInsufficientResources;
   3077       }
   3078     }
   3079 
   3080     if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
   3081       driver_context.input_buffer.alignment))
   3082     {
   3083       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   3084       close(pmem_fd);
   3085       return OMX_ErrorInsufficientResources;
   3086     }
   3087 
   3088     buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
   3089                     MAP_SHARED,pmem_fd,0);
   3090 
   3091     if (buf_addr == MAP_FAILED)
   3092     {
   3093       return OMX_ErrorInsufficientResources;
   3094     }
   3095 
   3096     driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr;
   3097     driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   3098     driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size;
   3099     driver_context.ptr_inputbuffer [i].offset = 0;
   3100 
   3101     setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   3102     memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i],
   3103             sizeof (vdec_bufferpayload));
   3104     ioctl_msg.inputparam  = &setbuffers;
   3105     ioctl_msg.outputparam = NULL;
   3106 
   3107     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
   3108          &ioctl_msg) < 0)
   3109     {
   3110       return OMX_ErrorInsufficientResources;
   3111     }
   3112 
   3113     *bufferHdr = (m_inp_mem_ptr + i);
   3114     input = *bufferHdr;
   3115     BITMASK_SET(&m_inp_bm_count,i);
   3116 
   3117     input->pBuffer           = (OMX_U8 *)buffer;
   3118     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   3119     input->nVersion.nVersion = OMX_SPEC_VERSION;
   3120     input->nAllocLen         = m_inp_buf_size;
   3121     input->pAppPrivate       = appData;
   3122     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   3123     input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i];
   3124   }
   3125   else
   3126   {
   3127     eRet = OMX_ErrorInsufficientResources;
   3128   }
   3129   return eRet;
   3130 }
   3131 
   3132 
   3133 /* ======================================================================
   3134 FUNCTION
   3135   omx_vdec::UseOutputBuffer
   3136 
   3137 DESCRIPTION
   3138   Helper function for Use buffer in the input pin
   3139 
   3140 PARAMETERS
   3141   None.
   3142 
   3143 RETURN VALUE
   3144   true/false
   3145 
   3146 ========================================================================== */
   3147 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
   3148                          OMX_IN OMX_HANDLETYPE            hComp,
   3149                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3150                          OMX_IN OMX_U32                   port,
   3151                          OMX_IN OMX_PTR                   appData,
   3152                          OMX_IN OMX_U32                   bytes,
   3153                          OMX_IN OMX_U8*                   buffer)
   3154 {
   3155   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3156   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   3157   unsigned                         i= 0; // Temporary counter
   3158 
   3159   if(!m_out_mem_ptr)
   3160   {
   3161     DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
   3162     output_use_buffer = true;
   3163     int nBufHdrSize        = 0;
   3164     int nPlatformEntrySize = 0;
   3165     int nPlatformListSize  = 0;
   3166     int nPMEMInfoSize = 0;
   3167     OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   3168     OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   3169     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   3170 
   3171     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
   3172     nBufHdrSize        = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
   3173 
   3174     nPMEMInfoSize      = m_out_buf_count *
   3175                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   3176     nPlatformListSize  = m_out_buf_count *
   3177                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   3178     nPlatformEntrySize = m_out_buf_count *
   3179                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   3180 
   3181     DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
   3182                          sizeof(OMX_BUFFERHEADERTYPE),
   3183                          nPMEMInfoSize,
   3184                          nPlatformListSize);
   3185     DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
   3186                          m_out_bm_count);
   3187 
   3188     /*
   3189      * Memory for output side involves the following:
   3190      * 1. Array of Buffer Headers
   3191      * 2. Platform specific information List
   3192      * 3. Platform specific Entry List
   3193      * 4. PMem Information entries
   3194      * 5. Bitmask array to hold the buffer allocation details
   3195      * In order to minimize the memory management entire allocation
   3196      * is done in one step.
   3197      */
   3198     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   3199     // Alloc mem for platform specific info
   3200     char *pPtr=NULL;
   3201     pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   3202                                      nPMEMInfoSize,1);
   3203     driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   3204       calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count);
   3205     driver_context.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   3206       calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count);
   3207 
   3208     if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
   3209        && driver_context.ptr_respbuffer)
   3210     {
   3211       bufHdr          =  m_out_mem_ptr;
   3212       m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   3213       m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   3214                         (((char *) m_platform_list)  + nPlatformListSize);
   3215       m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   3216                         (((char *) m_platform_entry) + nPlatformEntrySize);
   3217       pPlatformList   = m_platform_list;
   3218       pPlatformEntry  = m_platform_entry;
   3219       pPMEMInfo       = m_pmem_info;
   3220 
   3221       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   3222 
   3223       // Settting the entire storage nicely
   3224       DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
   3225       DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
   3226       for(i=0; i < m_out_buf_count ; i++)
   3227       {
   3228         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   3229         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   3230         // Set the values when we determine the right HxW param
   3231         bufHdr->nAllocLen          = bytes;
   3232         bufHdr->nFilledLen         = 0;
   3233         bufHdr->pAppPrivate        = appData;
   3234         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   3235         // Platform specific PMEM Information
   3236         // Initialize the Platform Entry
   3237         //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
   3238         pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   3239         pPlatformEntry->entry      = pPMEMInfo;
   3240         // Initialize the Platform List
   3241         pPlatformList->nEntries    = 1;
   3242         pPlatformList->entryList   = pPlatformEntry;
   3243         // Keep pBuffer NULL till vdec is opened
   3244         bufHdr->pBuffer            = NULL;
   3245 
   3246         pPMEMInfo->offset          =  0;
   3247         pPMEMInfo->pmem_fd = 0;
   3248         bufHdr->pPlatformPrivate = pPlatformList;
   3249 
   3250         driver_context.ptr_outputbuffer[i].pmem_fd = -1;
   3251 
   3252         /*Create a mapping between buffers*/
   3253         bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i];
   3254         driver_context.ptr_respbuffer[i].client_data = (void *) \
   3255                                             &driver_context.ptr_outputbuffer[i];
   3256         // Move the buffer and buffer header pointers
   3257         bufHdr++;
   3258         pPMEMInfo++;
   3259         pPlatformEntry++;
   3260         pPlatformList++;
   3261       }
   3262     }
   3263     else
   3264     {
   3265       DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
   3266                                         m_out_mem_ptr, pPtr);
   3267       if(m_out_mem_ptr)
   3268       {
   3269         free(m_out_mem_ptr);
   3270         m_out_mem_ptr = NULL;
   3271       }
   3272       if(pPtr)
   3273       {
   3274         free(pPtr);
   3275         pPtr = NULL;
   3276       }
   3277       if(driver_context.ptr_outputbuffer)
   3278       {
   3279         free(driver_context.ptr_outputbuffer);
   3280         driver_context.ptr_outputbuffer = NULL;
   3281       }
   3282       if(driver_context.ptr_respbuffer)
   3283       {
   3284         free(driver_context.ptr_respbuffer);
   3285         driver_context.ptr_respbuffer = NULL;
   3286       }
   3287       eRet =  OMX_ErrorInsufficientResources;
   3288     }
   3289   }
   3290 
   3291   for(i=0; i< m_out_buf_count; i++)
   3292   {
   3293     if(BITMASK_ABSENT(&m_out_bm_count,i))
   3294     {
   3295       break;
   3296     }
   3297   }
   3298 
   3299   if (eRet == OMX_ErrorNone)
   3300   {
   3301     if(i < m_out_buf_count)
   3302     {
   3303       driver_context.ptr_outputbuffer[i].pmem_fd = \
   3304         open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   3305 
   3306       if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
   3307       {
   3308         return OMX_ErrorInsufficientResources;
   3309       }
   3310 
   3311       if(driver_context.ptr_outputbuffer[i].pmem_fd == 0)
   3312       {
   3313         driver_context.ptr_outputbuffer[i].pmem_fd = \
   3314           open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   3315 
   3316         if (driver_context.ptr_outputbuffer[i].pmem_fd < 0)
   3317         {
   3318           return OMX_ErrorInsufficientResources;
   3319         }
   3320       }
   3321 
   3322       if(!align_pmem_buffers(driver_context.ptr_outputbuffer[i].pmem_fd,
   3323         m_out_buf_size, driver_context.output_buffer.alignment))
   3324       {
   3325         DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   3326         close(driver_context.ptr_outputbuffer[i].pmem_fd);
   3327         return OMX_ErrorInsufficientResources;
   3328       }
   3329 
   3330       driver_context.ptr_outputbuffer[i].bufferaddr =
   3331         (unsigned char *)mmap(NULL,m_out_buf_size,PROT_READ|PROT_WRITE,
   3332          MAP_SHARED,driver_context.ptr_outputbuffer[i].pmem_fd,0);
   3333 
   3334       if (driver_context.ptr_outputbuffer[i].bufferaddr == MAP_FAILED)
   3335       {
   3336         return OMX_ErrorInsufficientResources;
   3337       }
   3338       driver_context.ptr_outputbuffer[i].offset = 0;
   3339       m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset;
   3340       m_pmem_info[i].pmem_fd = driver_context.ptr_outputbuffer[i].pmem_fd;
   3341 
   3342       // found an empty buffer at i
   3343       *bufferHdr = (m_out_mem_ptr + i );
   3344       (*bufferHdr)->pBuffer = buffer;
   3345       (*bufferHdr)->pAppPrivate = appData;
   3346       BITMASK_SET(&m_out_bm_count,i);
   3347     }
   3348     else
   3349     {
   3350       DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
   3351       eRet = OMX_ErrorInsufficientResources;
   3352     }
   3353   }
   3354 
   3355   return eRet;
   3356 }
   3357 
   3358 /* ======================================================================
   3359 FUNCTION
   3360   omx_vdec::UseBuffer
   3361 
   3362 DESCRIPTION
   3363   OMX Use Buffer method implementation.
   3364 
   3365 PARAMETERS
   3366   <TBD>.
   3367 
   3368 RETURN VALUE
   3369   OMX Error None , if everything successful.
   3370 
   3371 ========================================================================== */
   3372 OMX_ERRORTYPE  omx_vdec::use_buffer(
   3373                          OMX_IN OMX_HANDLETYPE            hComp,
   3374                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3375                          OMX_IN OMX_U32                   port,
   3376                          OMX_IN OMX_PTR                   appData,
   3377                          OMX_IN OMX_U32                   bytes,
   3378                          OMX_IN OMX_U8*                   buffer)
   3379 {
   3380     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3381     if(m_state == OMX_StateInvalid)
   3382     {
   3383         DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
   3384         return OMX_ErrorInvalidState;
   3385     }
   3386     if(port == OMX_CORE_INPUT_PORT_INDEX)
   3387     {
   3388       eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   3389     }
   3390     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   3391     {
   3392       eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   3393     }
   3394     else
   3395     {
   3396       DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   3397       eRet = OMX_ErrorBadPortIndex;
   3398     }
   3399     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, eRet);
   3400 
   3401     if(eRet == OMX_ErrorNone)
   3402     {
   3403       if(allocate_done())
   3404       {
   3405         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3406         {
   3407           // Send the callback now
   3408           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   3409           post_event(OMX_CommandStateSet,OMX_StateIdle,
   3410                              OMX_COMPONENT_GENERATE_EVENT);
   3411         }
   3412       }
   3413       if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
   3414       {
   3415         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   3416         {
   3417           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   3418           post_event(OMX_CommandPortEnable,
   3419               OMX_CORE_INPUT_PORT_INDEX,
   3420               OMX_COMPONENT_GENERATE_EVENT);
   3421         }
   3422 
   3423       }
   3424       else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
   3425       {
   3426         if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   3427         {
   3428           BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3429           post_event(OMX_CommandPortEnable,
   3430                      OMX_CORE_OUTPUT_PORT_INDEX,
   3431                      OMX_COMPONENT_GENERATE_EVENT);
   3432           m_event_port_settings_sent = false;
   3433         }
   3434       }
   3435     }
   3436     return eRet;
   3437 }
   3438 
   3439 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   3440 {
   3441   unsigned int index = 0;
   3442 
   3443   if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
   3444   {
   3445     return OMX_ErrorBadParameter;
   3446   }
   3447 
   3448   index = bufferHdr - m_inp_mem_ptr;
   3449   DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
   3450 
   3451   if (index < m_inp_buf_count && driver_context.ptr_inputbuffer)
   3452   {
   3453     DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
   3454     if (driver_context.ptr_inputbuffer[index].pmem_fd > 0)
   3455     {
   3456        struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   3457        struct vdec_setbuffer_cmd setbuffers;
   3458        setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   3459        memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer[index],
   3460           sizeof (vdec_bufferpayload));
   3461        ioctl_msg.inputparam  = &setbuffers;
   3462        ioctl_msg.outputparam = NULL;
   3463        int ioctl_r = ioctl (driver_context.video_driver_fd,
   3464                             VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
   3465        if (ioctl_r < 0)
   3466        {
   3467           DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
   3468        }
   3469 
   3470        DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
   3471                     driver_context.ptr_inputbuffer[index].pmem_fd);
   3472        DEBUG_PRINT_LOW("\n unmap the input buffer size=%d  address = %d",
   3473                     driver_context.ptr_inputbuffer[index].mmaped_size,
   3474                     driver_context.ptr_inputbuffer[index].bufferaddr);
   3475        munmap (driver_context.ptr_inputbuffer[index].bufferaddr,
   3476                driver_context.ptr_inputbuffer[index].mmaped_size);
   3477        close (driver_context.ptr_inputbuffer[index].pmem_fd);
   3478        driver_context.ptr_inputbuffer[index].pmem_fd = -1;
   3479     }
   3480   }
   3481 
   3482   return OMX_ErrorNone;
   3483 }
   3484 
   3485 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   3486 {
   3487   unsigned int index = 0;
   3488 
   3489   if (bufferHdr == NULL || m_out_mem_ptr == NULL)
   3490   {
   3491     return OMX_ErrorBadParameter;
   3492   }
   3493 
   3494   index = bufferHdr - m_out_mem_ptr;
   3495   DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
   3496 
   3497   if (index < m_out_buf_count && driver_context.ptr_outputbuffer)
   3498   {
   3499     DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %x", index,
   3500                     driver_context.ptr_outputbuffer[index].bufferaddr);
   3501 
   3502     if (!gate_output_buffers)
   3503     {
   3504       struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   3505       struct vdec_setbuffer_cmd setbuffers;
   3506       setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   3507       memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer[index],
   3508         sizeof (vdec_bufferpayload));
   3509       ioctl_msg.inputparam  = &setbuffers;
   3510       ioctl_msg.outputparam = NULL;
   3511       DEBUG_PRINT_LOW("\nRelease the Output Buffer");
   3512       if (ioctl (driver_context.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
   3513             &ioctl_msg) < 0)
   3514         DEBUG_PRINT_ERROR("\nRelease output buffer failed in VCD");
   3515     }
   3516 
   3517     if (driver_context.ptr_outputbuffer[0].pmem_fd > 0)
   3518     {
   3519        DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
   3520                     driver_context.ptr_outputbuffer[0].pmem_fd);
   3521        DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d  address = %d",
   3522                     driver_context.ptr_outputbuffer[0].mmaped_size,
   3523                     driver_context.ptr_outputbuffer[0].bufferaddr);
   3524        munmap (driver_context.ptr_outputbuffer[0].bufferaddr,
   3525                driver_context.ptr_outputbuffer[0].mmaped_size);
   3526        close (driver_context.ptr_outputbuffer[0].pmem_fd);
   3527        driver_context.ptr_outputbuffer[0].pmem_fd = -1;
   3528     }
   3529   }
   3530 
   3531   return OMX_ErrorNone;
   3532 
   3533 }
   3534 
   3535 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   3536                                          OMX_BUFFERHEADERTYPE **bufferHdr,
   3537                                          OMX_U32              port,
   3538                                          OMX_PTR              appData,
   3539                                          OMX_U32              bytes)
   3540 {
   3541   OMX_BUFFERHEADERTYPE *input = NULL;
   3542   unsigned char *buf_addr = NULL;
   3543   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3544   unsigned   i = 0;
   3545 
   3546   /* Sanity Check*/
   3547   if (bufferHdr == NULL)
   3548   {
   3549     return OMX_ErrorBadParameter;
   3550   }
   3551 
   3552   if (m_inp_heap_ptr == NULL)
   3553   {
   3554     m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   3555                      calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
   3556     m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   3557                      calloc( (sizeof(OMX_BUFFERHEADERTYPE*)), m_inp_buf_count);
   3558 
   3559     if (m_inp_heap_ptr == NULL)
   3560     {
   3561       DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
   3562       return OMX_ErrorInsufficientResources;
   3563     }
   3564 
   3565     h264_scratch.nAllocLen = m_inp_buf_size;
   3566     h264_scratch.pBuffer = (OMX_U8 *)malloc (m_inp_buf_size);
   3567     h264_scratch.nFilledLen = 0;
   3568     h264_scratch.nOffset = 0;
   3569 
   3570     if (h264_scratch.pBuffer == NULL)
   3571     {
   3572       DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
   3573       return OMX_ErrorInsufficientResources;
   3574     }
   3575 
   3576     if (m_frame_parser.mutils == NULL)
   3577     {
   3578        m_frame_parser.mutils = new H264_Utils();
   3579 
   3580        if (m_frame_parser.mutils == NULL)
   3581        {
   3582          DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
   3583          return OMX_ErrorInsufficientResources;
   3584        }
   3585 
   3586        m_frame_parser.mutils->initialize_frame_checking_environment();
   3587        m_frame_parser.mutils->allocate_rbsp_buffer (m_inp_buf_size);
   3588     }
   3589   }
   3590 
   3591   /*Find a Free index*/
   3592   for(i=0; i< m_inp_buf_count; i++)
   3593   {
   3594     if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
   3595     {
   3596       DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
   3597       break;
   3598     }
   3599   }
   3600 
   3601   if (i < m_inp_buf_count)
   3602   {
   3603     buf_addr = (unsigned char *)malloc (m_inp_buf_size);
   3604 
   3605     if (buf_addr == NULL)
   3606     {
   3607       return OMX_ErrorInsufficientResources;
   3608     }
   3609 
   3610     *bufferHdr = (m_inp_heap_ptr + i);
   3611     input = *bufferHdr;
   3612     BITMASK_SET(&m_heap_inp_bm_count,i);
   3613 
   3614     input->pBuffer           = (OMX_U8 *)buf_addr;
   3615     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   3616     input->nVersion.nVersion = OMX_SPEC_VERSION;
   3617     input->nAllocLen         = m_inp_buf_size;
   3618     input->pAppPrivate       = appData;
   3619     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   3620     DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
   3621     eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   3622     DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
   3623     /*Add the Buffers to freeq*/
   3624     if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL))
   3625     {
   3626       DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
   3627       return OMX_ErrorInsufficientResources;
   3628     }
   3629   }
   3630   else
   3631   {
   3632     return OMX_ErrorBadParameter;
   3633   }
   3634 
   3635   return eRet;
   3636 
   3637 }
   3638 
   3639 
   3640 /* ======================================================================
   3641 FUNCTION
   3642   omx_vdec::AllocateInputBuffer
   3643 
   3644 DESCRIPTION
   3645   Helper function for allocate buffer in the input pin
   3646 
   3647 PARAMETERS
   3648   None.
   3649 
   3650 RETURN VALUE
   3651   true/false
   3652 
   3653 ========================================================================== */
   3654 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   3655                          OMX_IN OMX_HANDLETYPE            hComp,
   3656                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3657                          OMX_IN OMX_U32                   port,
   3658                          OMX_IN OMX_PTR                   appData,
   3659                          OMX_IN OMX_U32                   bytes)
   3660 {
   3661 
   3662   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3663   struct vdec_setbuffer_cmd setbuffers;
   3664   OMX_BUFFERHEADERTYPE *input = NULL;
   3665   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   3666   unsigned   i = 0;
   3667   unsigned char *buf_addr = NULL;
   3668   int pmem_fd = -1;
   3669 
   3670   if(bytes != m_inp_buf_size)
   3671   {
   3672     DEBUG_PRINT_LOW("\n Requested Size is wrong %d epected is %d",bytes,m_inp_buf_size);
   3673     //return OMX_ErrorBadParameter;
   3674   }
   3675 
   3676   if(!m_inp_mem_ptr)
   3677   {
   3678     DEBUG_PRINT_HIGH("\n Allocate i/p buffer case - Header List allocation");
   3679     DEBUG_PRINT_LOW("\n Allocating input buffer count %d ",m_inp_buf_count);
   3680     DEBUG_PRINT_LOW("\n Size of input buffer is %d",m_inp_buf_size);
   3681 
   3682     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   3683     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_inp_buf_count);
   3684 
   3685     if (m_inp_mem_ptr == NULL)
   3686     {
   3687       return OMX_ErrorInsufficientResources;
   3688     }
   3689 
   3690     driver_context.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   3691     calloc ((sizeof (struct vdec_bufferpayload)),m_inp_buf_count);
   3692 
   3693     if (driver_context.ptr_inputbuffer == NULL)
   3694     {
   3695       return OMX_ErrorInsufficientResources;
   3696     }
   3697 
   3698     for (i=0; i < m_inp_buf_count; i++)
   3699     {
   3700       driver_context.ptr_inputbuffer [i].pmem_fd = -1;
   3701     }
   3702   }
   3703 
   3704   for(i=0; i< m_inp_buf_count; i++)
   3705   {
   3706     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   3707     {
   3708       DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
   3709       break;
   3710     }
   3711   }
   3712 
   3713   if(i < m_inp_buf_count)
   3714   {
   3715     DEBUG_PRINT_LOW("\n Allocate input Buffer");
   3716     pmem_fd = open ("/dev/pmem_adsp", O_RDWR, O_SYNC);
   3717 
   3718     if (pmem_fd < 0)
   3719     {
   3720       DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
   3721       return OMX_ErrorInsufficientResources;
   3722     }
   3723 
   3724     if (pmem_fd == 0)
   3725     {
   3726       pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   3727 
   3728       if (pmem_fd < 0)
   3729       {
   3730         DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
   3731         return OMX_ErrorInsufficientResources;
   3732       }
   3733     }
   3734 
   3735     if(!align_pmem_buffers(pmem_fd, m_inp_buf_size,
   3736       driver_context.input_buffer.alignment))
   3737     {
   3738       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   3739       close(pmem_fd);
   3740       return OMX_ErrorInsufficientResources;
   3741     }
   3742 
   3743     buf_addr = (unsigned char *)mmap(NULL,m_inp_buf_size,PROT_READ|PROT_WRITE,
   3744                     MAP_SHARED,pmem_fd,0);
   3745 
   3746     if (buf_addr == MAP_FAILED)
   3747     {
   3748       DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
   3749       return OMX_ErrorInsufficientResources;
   3750     }
   3751 
   3752     driver_context.ptr_inputbuffer [i].bufferaddr = buf_addr;
   3753     driver_context.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   3754     driver_context.ptr_inputbuffer [i].buffer_len = m_inp_buf_size;
   3755     driver_context.ptr_inputbuffer [i].mmaped_size = m_inp_buf_size;
   3756     driver_context.ptr_inputbuffer [i].offset = 0;
   3757 
   3758     setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   3759     memcpy (&setbuffers.buffer,&driver_context.ptr_inputbuffer [i],
   3760             sizeof (vdec_bufferpayload));
   3761     ioctl_msg.inputparam  = &setbuffers;
   3762     ioctl_msg.outputparam = NULL;
   3763 
   3764     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
   3765          &ioctl_msg) < 0)
   3766     {
   3767       DEBUG_PRINT_ERROR("\n Set Buffers Failed");
   3768       return OMX_ErrorInsufficientResources;
   3769     }
   3770 
   3771     *bufferHdr = (m_inp_mem_ptr + i);
   3772     input = *bufferHdr;
   3773     BITMASK_SET(&m_inp_bm_count,i);
   3774     DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
   3775 
   3776     input->pBuffer           = (OMX_U8 *)buf_addr;
   3777     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   3778     input->nVersion.nVersion = OMX_SPEC_VERSION;
   3779     input->nAllocLen         = m_inp_buf_size;
   3780     input->pAppPrivate       = appData;
   3781     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   3782     input->pInputPortPrivate = (void *)&driver_context.ptr_inputbuffer [i];
   3783   }
   3784   else
   3785   {
   3786     DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
   3787     eRet = OMX_ErrorInsufficientResources;
   3788   }
   3789   return eRet;
   3790 }
   3791 
   3792 
   3793 /* ======================================================================
   3794 FUNCTION
   3795   omx_vdec::AllocateOutputBuffer
   3796 
   3797 DESCRIPTION
   3798   Helper fn for AllocateBuffer in the output pin
   3799 
   3800 PARAMETERS
   3801   <TBD>.
   3802 
   3803 RETURN VALUE
   3804   OMX Error None if everything went well.
   3805 
   3806 ========================================================================== */
   3807 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   3808                          OMX_IN OMX_HANDLETYPE            hComp,
   3809                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3810                          OMX_IN OMX_U32                   port,
   3811                          OMX_IN OMX_PTR                   appData,
   3812                          OMX_IN OMX_U32                   bytes)
   3813 {
   3814   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3815   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   3816   unsigned                         i= 0; // Temporary counter
   3817   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   3818   struct vdec_setbuffer_cmd setbuffers;
   3819 
   3820   if(!m_out_mem_ptr)
   3821   {
   3822     DEBUG_PRINT_HIGH("\n Allocate o/p buffer case - Header List allocation");
   3823     int nBufHdrSize        = 0;
   3824     int nPlatformEntrySize = 0;
   3825     int nPlatformListSize  = 0;
   3826     int nPMEMInfoSize = 0;
   3827     int pmem_fd = -1;
   3828     unsigned char *pmem_baseaddress = NULL;
   3829 
   3830     OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   3831     OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   3832     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   3833 
   3834     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_out_buf_count);
   3835     nBufHdrSize        = m_out_buf_count * sizeof(OMX_BUFFERHEADERTYPE);
   3836 
   3837     nPMEMInfoSize      = m_out_buf_count *
   3838                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   3839     nPlatformListSize  = m_out_buf_count *
   3840                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   3841     nPlatformEntrySize = m_out_buf_count *
   3842                          sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   3843 
   3844     DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
   3845                          sizeof(OMX_BUFFERHEADERTYPE),
   3846                          nPMEMInfoSize,
   3847                          nPlatformListSize);
   3848     DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
   3849                          m_out_buf_count);
   3850 
   3851     pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   3852 
   3853     if (pmem_fd < 0)
   3854     {
   3855       DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
   3856       return OMX_ErrorInsufficientResources;
   3857     }
   3858 
   3859     if(pmem_fd == 0)
   3860     {
   3861       pmem_fd = open ("/dev/pmem_adsp", O_RDWR | O_SYNC);
   3862 
   3863       if (pmem_fd < 0)
   3864       {
   3865         DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",m_out_buf_size);
   3866         return OMX_ErrorInsufficientResources;
   3867       }
   3868     }
   3869 
   3870     if(!align_pmem_buffers(pmem_fd, m_out_buf_size * m_out_buf_count,
   3871       driver_context.output_buffer.alignment))
   3872     {
   3873       DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   3874       close(pmem_fd);
   3875       return OMX_ErrorInsufficientResources;
   3876     }
   3877 
   3878     pmem_baseaddress = (unsigned char *)mmap(NULL,(m_out_buf_size * m_out_buf_count),
   3879                        PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   3880     m_heap_ptr = new VideoHeap (pmem_fd,
   3881                                    m_out_buf_size*m_out_buf_count,
   3882                                    pmem_baseaddress);
   3883 
   3884 
   3885     if (pmem_baseaddress == MAP_FAILED)
   3886     {
   3887       DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",m_out_buf_size);
   3888       return OMX_ErrorInsufficientResources;
   3889     }
   3890     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   3891     // Alloc mem for platform specific info
   3892     char *pPtr=NULL;
   3893     pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   3894                                      nPMEMInfoSize,1);
   3895     driver_context.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   3896       calloc (sizeof(struct vdec_bufferpayload),m_out_buf_count);
   3897     driver_context.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   3898       calloc (sizeof (struct vdec_output_frameinfo),m_out_buf_count);
   3899 
   3900     if(m_out_mem_ptr && pPtr && driver_context.ptr_outputbuffer
   3901        && driver_context.ptr_respbuffer)
   3902     {
   3903       driver_context.ptr_outputbuffer[0].mmaped_size =
   3904         (m_out_buf_size * m_out_buf_count);
   3905       bufHdr          =  m_out_mem_ptr;
   3906       m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   3907       m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   3908                         (((char *) m_platform_list)  + nPlatformListSize);
   3909       m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   3910                         (((char *) m_platform_entry) + nPlatformEntrySize);
   3911       pPlatformList   = m_platform_list;
   3912       pPlatformEntry  = m_platform_entry;
   3913       pPMEMInfo       = m_pmem_info;
   3914 
   3915       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   3916 
   3917       // Settting the entire storage nicely
   3918       DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
   3919       DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
   3920       for(i=0; i < m_out_buf_count ; i++)
   3921       {
   3922         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   3923         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   3924         // Set the values when we determine the right HxW param
   3925         bufHdr->nAllocLen          = bytes;
   3926         bufHdr->nFilledLen         = 0;
   3927         bufHdr->pAppPrivate        = appData;
   3928         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   3929         // Platform specific PMEM Information
   3930         // Initialize the Platform Entry
   3931         //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
   3932         pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   3933         pPlatformEntry->entry      = pPMEMInfo;
   3934         // Initialize the Platform List
   3935         pPlatformList->nEntries    = 1;
   3936         pPlatformList->entryList   = pPlatformEntry;
   3937         // Keep pBuffer NULL till vdec is opened
   3938         bufHdr->pBuffer            = NULL;
   3939         bufHdr->nOffset            = 0;
   3940 
   3941         pPMEMInfo->offset          =  m_out_buf_size*i;
   3942         pPMEMInfo->pmem_fd = 0;
   3943         bufHdr->pPlatformPrivate = pPlatformList;
   3944 
   3945         driver_context.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   3946 
   3947         /*Create a mapping between buffers*/
   3948         bufHdr->pOutputPortPrivate = &driver_context.ptr_respbuffer[i];
   3949         driver_context.ptr_respbuffer[i].client_data = (void *) \
   3950                                             &driver_context.ptr_outputbuffer[i];
   3951         driver_context.ptr_outputbuffer[i].offset = m_out_buf_size*i;
   3952         driver_context.ptr_outputbuffer[i].bufferaddr = \
   3953           pmem_baseaddress + (m_out_buf_size*i);
   3954 
   3955         DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",\
   3956                      pmem_fd,driver_context.ptr_outputbuffer[i].offset,driver_context.ptr_outputbuffer[i].bufferaddr);
   3957         // Move the buffer and buffer header pointers
   3958         bufHdr++;
   3959         pPMEMInfo++;
   3960         pPlatformEntry++;
   3961         pPlatformList++;
   3962       }
   3963     }
   3964     else
   3965     {
   3966       DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
   3967                                         m_out_mem_ptr, pPtr);
   3968       if(m_out_mem_ptr)
   3969       {
   3970         free(m_out_mem_ptr);
   3971         m_out_mem_ptr = NULL;
   3972       }
   3973       if(pPtr)
   3974       {
   3975         free(pPtr);
   3976         pPtr = NULL;
   3977       }
   3978       if(driver_context.ptr_outputbuffer)
   3979       {
   3980         free(driver_context.ptr_outputbuffer);
   3981         driver_context.ptr_outputbuffer = NULL;
   3982       }
   3983       if(driver_context.ptr_respbuffer)
   3984       {
   3985         free(driver_context.ptr_respbuffer);
   3986         driver_context.ptr_respbuffer = NULL;
   3987       }
   3988       eRet =  OMX_ErrorInsufficientResources;
   3989     }
   3990   }
   3991 
   3992   for(i=0; i< m_out_buf_count; i++)
   3993   {
   3994     if(BITMASK_ABSENT(&m_out_bm_count,i))
   3995     {
   3996       DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
   3997       break;
   3998     }
   3999   }
   4000 
   4001   if (eRet == OMX_ErrorNone)
   4002   {
   4003     if(i < m_out_buf_count)
   4004     {
   4005       m_pmem_info[i].offset = driver_context.ptr_outputbuffer[i].offset;
   4006       m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr.get ();
   4007       driver_context.ptr_outputbuffer[i].buffer_len = m_out_buf_size;
   4008       //driver_context.ptr_outputbuffer[i].mmaped_size = m_out_buf_size;
   4009      if(!gate_output_buffers)
   4010      {
   4011      setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   4012      memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i],
   4013              sizeof (vdec_bufferpayload));
   4014      ioctl_msg.inputparam  = &setbuffers;
   4015      ioctl_msg.outputparam = NULL;
   4016 
   4017      DEBUG_PRINT_LOW("\n Set the Output Buffer");
   4018      if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
   4019           &ioctl_msg) < 0)
   4020      {
   4021        DEBUG_PRINT_ERROR("\n Set output buffer failed");
   4022        return OMX_ErrorInsufficientResources;
   4023      }
   4024      }
   4025 
   4026       // found an empty buffer at i
   4027       *bufferHdr = (m_out_mem_ptr + i );
   4028       (*bufferHdr)->pBuffer = driver_context.ptr_outputbuffer[i].bufferaddr;
   4029       (*bufferHdr)->pAppPrivate = appData;
   4030       BITMASK_SET(&m_out_bm_count,i);
   4031     }
   4032     else
   4033     {
   4034       DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
   4035       eRet = OMX_ErrorInsufficientResources;
   4036     }
   4037   }
   4038 
   4039   return eRet;
   4040 }
   4041 
   4042 
   4043 // AllocateBuffer  -- API Call
   4044 /* ======================================================================
   4045 FUNCTION
   4046   omx_vdec::AllocateBuffer
   4047 
   4048 DESCRIPTION
   4049   Returns zero if all the buffers released..
   4050 
   4051 PARAMETERS
   4052   None.
   4053 
   4054 RETURN VALUE
   4055   true/false
   4056 
   4057 ========================================================================== */
   4058 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   4059                                      OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4060                                      OMX_IN OMX_U32                        port,
   4061                                      OMX_IN OMX_PTR                     appData,
   4062                                      OMX_IN OMX_U32                       bytes)
   4063 {
   4064     unsigned i = 0;
   4065     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   4066 
   4067     DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
   4068     if(m_state == OMX_StateInvalid)
   4069     {
   4070         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
   4071         return OMX_ErrorInvalidState;
   4072     }
   4073 
   4074     if(port == OMX_CORE_INPUT_PORT_INDEX)
   4075     {
   4076       if (arbitrary_bytes)
   4077       {
   4078           eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   4079       }
   4080       else
   4081       {
   4082         eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   4083       }
   4084     }
   4085     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   4086     {
   4087       eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   4088     }
   4089     else
   4090     {
   4091       DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   4092       eRet = OMX_ErrorBadPortIndex;
   4093     }
   4094     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   4095     if(eRet == OMX_ErrorNone)
   4096     {
   4097         if(allocate_done()){
   4098             if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   4099             {
   4100                 // Send the callback now
   4101                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   4102                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   4103                                    OMX_COMPONENT_GENERATE_EVENT);
   4104             }
   4105         }
   4106         if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
   4107         {
   4108           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   4109           {
   4110              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   4111              post_event(OMX_CommandPortEnable,
   4112                         OMX_CORE_INPUT_PORT_INDEX,
   4113                         OMX_COMPONENT_GENERATE_EVENT);
   4114           }
   4115         }
   4116         if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
   4117             {
   4118           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   4119           {
   4120              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   4121                 post_event(OMX_CommandPortEnable,
   4122                            OMX_CORE_OUTPUT_PORT_INDEX,
   4123                            OMX_COMPONENT_GENERATE_EVENT);
   4124                 m_event_port_settings_sent = false;
   4125             }
   4126         }
   4127     }
   4128     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
   4129     return eRet;
   4130 }
   4131 
   4132 // Free Buffer - API call
   4133 /* ======================================================================
   4134 FUNCTION
   4135   omx_vdec::FreeBuffer
   4136 
   4137 DESCRIPTION
   4138 
   4139 PARAMETERS
   4140   None.
   4141 
   4142 RETURN VALUE
   4143   true/false
   4144 
   4145 ========================================================================== */
   4146 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   4147                                       OMX_IN OMX_U32                 port,
   4148                                       OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4149 {
   4150     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4151     unsigned int nPortIndex;
   4152 
   4153     DEBUG_PRINT_LOW("In for decoder free_buffer \n");
   4154 
   4155     if(m_state == OMX_StateIdle &&
   4156        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   4157     {
   4158         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
   4159     }
   4160     else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   4161             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
   4162     {
   4163         DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
   4164     }
   4165     else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
   4166     {
   4167         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
   4168         post_event(OMX_EventError,
   4169                    OMX_ErrorPortUnpopulated,
   4170                    OMX_COMPONENT_GENERATE_EVENT);
   4171 
   4172         return eRet;
   4173     }
   4174     else if (m_state != OMX_StateInvalid)
   4175     {
   4176         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
   4177         post_event(OMX_EventError,
   4178                    OMX_ErrorPortUnpopulated,
   4179                    OMX_COMPONENT_GENERATE_EVENT);
   4180     }
   4181 
   4182     if(port == OMX_CORE_INPUT_PORT_INDEX)
   4183     {
   4184       /*Check if arbitrary bytes*/
   4185       if (!arbitrary_bytes)
   4186       {
   4187        // check if the buffer is valid
   4188         nPortIndex = buffer - m_inp_mem_ptr;
   4189       }
   4190       else
   4191       {
   4192          nPortIndex = buffer - m_inp_heap_ptr;
   4193       }
   4194 
   4195         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
   4196         if(nPortIndex < m_inp_buf_count)
   4197         {
   4198           // Clear the bit associated with it.
   4199           BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   4200 
   4201           if (arbitrary_bytes)
   4202           {
   4203             if (m_inp_heap_ptr[nPortIndex].pBuffer)
   4204             {
   4205               BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   4206               DEBUG_PRINT_LOW("\n Free Heap Buffer index %d",nPortIndex);
   4207               free (m_inp_heap_ptr[nPortIndex].pBuffer);
   4208               m_inp_heap_ptr[nPortIndex].pBuffer = NULL;
   4209             }
   4210             if (m_phdr_pmem_ptr[nPortIndex])
   4211             {
   4212               DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
   4213               free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   4214             }
   4215           }
   4216           else
   4217           {
   4218             free_input_buffer(buffer);
   4219           }
   4220 
   4221           m_inp_bPopulated = OMX_FALSE;
   4222 
   4223           /*Free the Buffer Header*/
   4224           if (release_input_done())
   4225           {
   4226             DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
   4227             input_use_buffer = false;
   4228             if (arbitrary_bytes)
   4229             {
   4230               if (m_frame_parser.mutils)
   4231               {
   4232                 DEBUG_PRINT_LOW("\n Free utils parser");
   4233                 delete (m_frame_parser.mutils);
   4234                 m_frame_parser.mutils = NULL;
   4235               }
   4236 
   4237               if (m_inp_heap_ptr)
   4238               {
   4239                 DEBUG_PRINT_LOW("\n Free input Heap Pointer");
   4240                 free (m_inp_heap_ptr);
   4241                 m_inp_heap_ptr = NULL;
   4242               }
   4243 
   4244               if (m_phdr_pmem_ptr)
   4245               {
   4246                 DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
   4247                 free (m_phdr_pmem_ptr);
   4248                 m_phdr_pmem_ptr = NULL;
   4249               }
   4250             }
   4251             if (m_inp_mem_ptr)
   4252             {
   4253               DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
   4254               free (m_inp_mem_ptr);
   4255               m_inp_mem_ptr = NULL;
   4256             }
   4257 
   4258             if (driver_context.ptr_inputbuffer)
   4259             {
   4260               DEBUG_PRINT_LOW("\n Free Driver Context pointer");
   4261               free (driver_context.ptr_inputbuffer);
   4262               driver_context.ptr_inputbuffer = NULL;
   4263             }
   4264           }
   4265 
   4266         }
   4267         else
   4268         {
   4269             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
   4270             eRet = OMX_ErrorBadPortIndex;
   4271         }
   4272 
   4273         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   4274            && release_input_done())
   4275         {
   4276             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   4277             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   4278             post_event(OMX_CommandPortDisable,
   4279                        OMX_CORE_INPUT_PORT_INDEX,
   4280                        OMX_COMPONENT_GENERATE_EVENT);
   4281         }
   4282     }
   4283     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   4284     {
   4285         // check if the buffer is valid
   4286         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
   4287         if(nPortIndex < m_out_buf_count)
   4288         {
   4289             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
   4290             // Clear the bit associated with it.
   4291             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   4292             m_out_bPopulated = OMX_FALSE;
   4293             free_output_buffer (buffer);
   4294 
   4295             if (release_output_done())
   4296             {
   4297               DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
   4298               output_use_buffer = false;
   4299               if (m_out_mem_ptr)
   4300               {
   4301                 free (m_out_mem_ptr);
   4302                 m_out_mem_ptr = NULL;
   4303               }
   4304               if (driver_context.ptr_respbuffer)
   4305               {
   4306                 free (driver_context.ptr_respbuffer);
   4307                 driver_context.ptr_respbuffer = NULL;
   4308               }
   4309               if (driver_context.ptr_outputbuffer)
   4310               {
   4311                 free (driver_context.ptr_outputbuffer);
   4312                 driver_context.ptr_outputbuffer = NULL;
   4313               }
   4314             }
   4315         }
   4316         else
   4317         {
   4318             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
   4319             eRet = OMX_ErrorBadPortIndex;
   4320         }
   4321         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   4322            && release_output_done() )
   4323         {
   4324             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
   4325 
   4326                 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   4327                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   4328                 post_event(OMX_CommandPortDisable,
   4329                            OMX_CORE_OUTPUT_PORT_INDEX,
   4330                            OMX_COMPONENT_GENERATE_EVENT);
   4331         }
   4332     }
   4333     else
   4334     {
   4335         eRet = OMX_ErrorBadPortIndex;
   4336     }
   4337     if((eRet == OMX_ErrorNone) &&
   4338        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   4339     {
   4340         if(release_done())
   4341         {
   4342             // Send the callback now
   4343             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   4344             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   4345                                       OMX_COMPONENT_GENERATE_EVENT);
   4346         }
   4347     }
   4348     return eRet;
   4349 }
   4350 
   4351 
   4352 /* ======================================================================
   4353 FUNCTION
   4354   omx_vdec::EmptyThisBuffer
   4355 
   4356 DESCRIPTION
   4357   This routine is used to push the encoded video frames to
   4358   the video decoder.
   4359 
   4360 PARAMETERS
   4361   None.
   4362 
   4363 RETURN VALUE
   4364   OMX Error None if everything went successful.
   4365 
   4366 ========================================================================== */
   4367 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   4368                                            OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4369 {
   4370   OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   4371   unsigned int nBufferIndex = m_inp_buf_count;
   4372 
   4373   if(m_state == OMX_StateInvalid)
   4374   {
   4375       DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
   4376       return OMX_ErrorInvalidState;
   4377   }
   4378 
   4379   if (buffer == NULL)
   4380   {
   4381     DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
   4382     return OMX_ErrorBadParameter;
   4383   }
   4384 
   4385   if (arbitrary_bytes)
   4386   {
   4387     nBufferIndex = buffer - m_inp_heap_ptr;
   4388   }
   4389   else
   4390   {
   4391     nBufferIndex = buffer - m_inp_mem_ptr;
   4392   }
   4393 
   4394   if (nBufferIndex > m_inp_buf_count )
   4395   {
   4396     DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
   4397     return OMX_ErrorBadParameter;
   4398   }
   4399 
   4400   DEBUG_PRINT_LOW("\n ETB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   4401   if (arbitrary_bytes)
   4402   {
   4403     post_event ((unsigned)hComp,(unsigned)buffer,
   4404                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   4405   }
   4406   else
   4407   {
   4408     post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
   4409   }
   4410   return OMX_ErrorNone;
   4411 }
   4412 
   4413 /* ======================================================================
   4414 FUNCTION
   4415   omx_vdec::empty_this_buffer_proxy
   4416 
   4417 DESCRIPTION
   4418   This routine is used to push the encoded video frames to
   4419   the video decoder.
   4420 
   4421 PARAMETERS
   4422   None.
   4423 
   4424 RETURN VALUE
   4425   OMX Error None if everything went successful.
   4426 
   4427 ========================================================================== */
   4428 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
   4429                                                  OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4430 {
   4431   int push_cnt = 0,i=0;
   4432   unsigned nPortIndex = 0;
   4433   OMX_ERRORTYPE ret = OMX_ErrorNone;
   4434   struct vdec_input_frameinfo frameinfo;
   4435   struct vdec_bufferpayload *temp_buffer;
   4436   struct vdec_ioctl_msg ioctl_msg;
   4437   struct vdec_seqheader seq_header;
   4438   bool port_setting_changed = true;
   4439 
   4440   /*Should we generate a Aync error event*/
   4441   if (buffer == NULL || buffer->pInputPortPrivate == NULL)
   4442   {
   4443     DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
   4444     return OMX_ErrorBadParameter;
   4445   }
   4446 
   4447   nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   4448 
   4449   if (nPortIndex > m_inp_buf_count)
   4450   {
   4451     DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   4452         nPortIndex);
   4453     return OMX_ErrorBadParameter;
   4454   }
   4455 
   4456   pending_input_buffers++;
   4457 
   4458   if( input_flush_progress == true || m_ineos_reached == 1)
   4459   {
   4460     DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
   4461     post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
   4462                      OMX_COMPONENT_GENERATE_EBD);
   4463     return OMX_ErrorNone;
   4464   }
   4465 
   4466   if(m_event_port_settings_sent && !arbitrary_bytes)
   4467   {
   4468     post_event((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
   4469     return OMX_ErrorNone;
   4470   }
   4471 
   4472   temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   4473 
   4474   if ((temp_buffer -  driver_context.ptr_inputbuffer) > m_inp_buf_count)
   4475   {
   4476     return OMX_ErrorBadParameter;
   4477   }
   4478 
   4479   DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   4480   /*for use buffer we need to memcpy the data*/
   4481   temp_buffer->buffer_len = buffer->nFilledLen;
   4482 
   4483   if (input_use_buffer)
   4484   {
   4485     if (buffer->nFilledLen <= temp_buffer->buffer_len)
   4486     {
   4487       memcpy (temp_buffer->bufferaddr,(buffer->pBuffer + buffer->nOffset),
   4488               buffer->nFilledLen);
   4489     }
   4490     else
   4491     {
   4492       return OMX_ErrorBadParameter;
   4493     }
   4494 
   4495   }
   4496 
   4497   if (!arbitrary_bytes && first_frame < 2  && codec_type_parse == CODEC_TYPE_MPEG4)
   4498   {
   4499 
   4500     if (first_frame == 0)
   4501     {
   4502        first_buffer = (unsigned char *)malloc (m_inp_buf_size);
   4503        DEBUG_PRINT_LOW("\n Copied the first buffer data size %d ",
   4504                     temp_buffer->buffer_len);
   4505        first_frame = 1;
   4506        memcpy (first_buffer,temp_buffer->bufferaddr,temp_buffer->buffer_len);
   4507        first_frame_size = buffer->nFilledLen;
   4508        buffer->nFilledLen = 0;
   4509        post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
   4510                    OMX_COMPONENT_GENERATE_EBD);
   4511        return OMX_ErrorNone;
   4512     }
   4513     else if (first_frame == 1)
   4514     {
   4515        first_frame = 2;
   4516        DEBUG_PRINT_LOW("\n Second buffer copy the header size %d frame size %d",
   4517                     first_frame_size,temp_buffer->buffer_len);
   4518        memcpy (&first_buffer [first_frame_size],temp_buffer->bufferaddr,
   4519                temp_buffer->buffer_len);
   4520        first_frame_size += temp_buffer->buffer_len;
   4521        memcpy (temp_buffer->bufferaddr,first_buffer,first_frame_size);
   4522        temp_buffer->buffer_len = first_frame_size;
   4523        free (first_buffer);
   4524     }
   4525   }
   4526 
   4527   frameinfo.bufferaddr = temp_buffer->bufferaddr;
   4528   frameinfo.client_data = (void *) buffer;
   4529   frameinfo.datalen = temp_buffer->buffer_len;
   4530   frameinfo.flags = 0;
   4531   frameinfo.offset = buffer->nOffset;
   4532   frameinfo.pmem_fd = temp_buffer->pmem_fd;
   4533   frameinfo.pmem_offset = temp_buffer->offset;
   4534   frameinfo.timestamp = buffer->nTimeStamp;
   4535 
   4536 #if BITSTREAM_LOG
   4537   int bytes_written;
   4538   bytes_written = fwrite((const char *)temp_buffer->bufferaddr,
   4539                           temp_buffer->buffer_len,1,outputBufferFile1);
   4540 
   4541 #endif
   4542 
   4543   if(!set_seq_header_done)
   4544   {
   4545     set_seq_header_done = true;
   4546     DEBUG_PRINT_HIGH("\n Set Sequence Header");
   4547     seq_header.ptr_seqheader = frameinfo.bufferaddr;
   4548     seq_header.seq_header_len = frameinfo.datalen;
   4549     seq_header.pmem_fd = frameinfo.pmem_fd;
   4550     seq_header.pmem_offset = frameinfo.pmem_offset;
   4551     ioctl_msg.inputparam = &seq_header;
   4552     ioctl_msg.outputparam = NULL;
   4553     if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_SET_SEQUENCE_HEADER,
   4554               &ioctl_msg) < 0)
   4555     {
   4556       DEBUG_PRINT_ERROR("\n Set Sequence Header Failed");
   4557       /*Generate an async error and move to invalid state*/
   4558       return OMX_ErrorBadParameter;
   4559     }
   4560     if(omx_vdec_check_port_settings (&port_setting_changed) != OMX_ErrorNone)
   4561     {
   4562       DEBUG_PRINT_ERROR("\n Check port setting failed");
   4563       return OMX_ErrorBadParameter;
   4564     }
   4565 
   4566     if(port_setting_changed)
   4567     {
   4568       DEBUG_PRINT_HIGH("\n Port settings changed");
   4569       m_event_port_settings_sent = true;
   4570       m_cb.EventHandler(&m_cmp, m_app_data,OMX_EventPortSettingsChanged,
   4571                           OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
   4572       DEBUG_PRINT_HIGH("\n EventHandler for Port Setting changed done");
   4573       return OMX_ErrorNone;
   4574     }
   4575     else
   4576     {
   4577       if(!register_output_buffers())
   4578       {
   4579         DEBUG_PRINT_ERROR("\n register output failed");
   4580         return OMX_ErrorBadParameter;
   4581       }
   4582       DEBUG_PRINT_HIGH("\n Port settings Not changed");
   4583     }
   4584   }
   4585 
   4586   if (temp_buffer->buffer_len == 0 || (buffer->nFlags & 0x01))
   4587   {
   4588     DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
   4589     frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   4590     m_ineos_reached = 1;
   4591   }
   4592 
   4593   sent_first_frame = true;
   4594   DEBUG_PRINT_LOW("\n Decode Input Frame Size %d",frameinfo.datalen);
   4595   ioctl_msg.inputparam = &frameinfo;
   4596   ioctl_msg.outputparam = NULL;
   4597 
   4598   if (ioctl(driver_context.video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
   4599             &ioctl_msg) < 0)
   4600   {
   4601     /*Generate an async error and move to invalid state*/
   4602     return OMX_ErrorBadParameter;
   4603   }
   4604 
   4605   return ret;
   4606 }
   4607 
   4608 /* ======================================================================
   4609 FUNCTION
   4610   omx_vdec::FillThisBuffer
   4611 
   4612 DESCRIPTION
   4613   IL client uses this method to release the frame buffer
   4614   after displaying them.
   4615 
   4616 PARAMETERS
   4617   None.
   4618 
   4619 RETURN VALUE
   4620   true/false
   4621 
   4622 ========================================================================== */
   4623 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   4624                                           OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   4625 {
   4626 
   4627   if(m_state == OMX_StateInvalid)
   4628   {
   4629       DEBUG_PRINT_ERROR("FTB in Invalid State\n");
   4630       return OMX_ErrorInvalidState;
   4631   }
   4632 
   4633   if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_size))
   4634   {
   4635     return OMX_ErrorBadParameter;
   4636   }
   4637 
   4638   DEBUG_PRINT_LOW("\n FTB: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   4639   post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
   4640   return OMX_ErrorNone;
   4641 }
   4642 /* ======================================================================
   4643 FUNCTION
   4644   omx_vdec::fill_this_buffer_proxy
   4645 
   4646 DESCRIPTION
   4647   IL client uses this method to release the frame buffer
   4648   after displaying them.
   4649 
   4650 PARAMETERS
   4651   None.
   4652 
   4653 RETURN VALUE
   4654   true/false
   4655 
   4656 ========================================================================== */
   4657 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   4658                          OMX_IN OMX_HANDLETYPE        hComp,
   4659                          OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   4660 {
   4661   OMX_ERRORTYPE nRet = OMX_ErrorNone;
   4662   struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
   4663   OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   4664   struct vdec_fillbuffer_cmd fillbuffer;
   4665   struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   4666   struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   4667 
   4668 
   4669   if (bufferAdd == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count) )
   4670   {
   4671     return OMX_ErrorBadParameter;
   4672   }
   4673 
   4674   DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   4675       bufferAdd, bufferAdd->pBuffer);
   4676   /*Return back the output buffer to client*/
   4677   if( (m_event_port_settings_sent == true) || (m_out_bEnabled != OMX_TRUE)
   4678       || output_flush_progress == true || m_outeos_reached == 1)
   4679   {
   4680     DEBUG_PRINT_LOW("\n Output Buffers return in EOS condition");
   4681     buffer->nFlags |= m_outeos_reached;
   4682     m_cb.FillBufferDone (hComp,m_app_data,buffer);
   4683     return OMX_ErrorNone;
   4684   }
   4685   pending_output_buffers++;
   4686   ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   4687   if (ptr_respbuffer)
   4688   {
   4689     ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   4690   }
   4691 
   4692   if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
   4693   {
   4694     return OMX_ErrorBadParameter;
   4695   }
   4696 
   4697   memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
   4698           sizeof(struct vdec_bufferpayload));
   4699   fillbuffer.client_data = bufferAdd;
   4700 
   4701   ioctl_msg.inputparam = &fillbuffer;
   4702   ioctl_msg.outputparam = NULL;
   4703   if (ioctl (driver_context.video_driver_fd,
   4704          VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0)
   4705   {
   4706     DEBUG_PRINT_ERROR("\n Decoder frame failed");
   4707     m_cb.FillBufferDone (hComp,m_app_data,buffer);
   4708     return OMX_ErrorBadParameter;
   4709   }
   4710 
   4711   if(gate_input_buffers)
   4712   {
   4713     gate_input_buffers = false;
   4714     if(pdest_frame)
   4715     {
   4716       /*Push the frame to the Decoder*/
   4717       if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
   4718       {
   4719         return OMX_ErrorBadParameter;
   4720       }
   4721       frame_count++;
   4722       pdest_frame = NULL;
   4723     }
   4724   }
   4725   return OMX_ErrorNone;
   4726 }
   4727 
   4728 /* ======================================================================
   4729 FUNCTION
   4730   omx_vdec::SetCallbacks
   4731 
   4732 DESCRIPTION
   4733   Set the callbacks.
   4734 
   4735 PARAMETERS
   4736   None.
   4737 
   4738 RETURN VALUE
   4739   OMX Error None if everything successful.
   4740 
   4741 ========================================================================== */
   4742 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   4743                                            OMX_IN OMX_CALLBACKTYPE* callbacks,
   4744                                            OMX_IN OMX_PTR             appData)
   4745 {
   4746 
   4747   m_cb       = *callbacks;
   4748   DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   4749                m_cb.EventHandler,m_cb.FillBufferDone);
   4750   m_app_data =    appData;
   4751   return OMX_ErrorNotImplemented;
   4752 }
   4753 
   4754 /* ======================================================================
   4755 FUNCTION
   4756   omx_vdec::ComponentDeInit
   4757 
   4758 DESCRIPTION
   4759   Destroys the component and release memory allocated to the heap.
   4760 
   4761 PARAMETERS
   4762   <TBD>.
   4763 
   4764 RETURN VALUE
   4765   OMX Error None if everything successful.
   4766 
   4767 ========================================================================== */
   4768 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   4769 {
   4770     int i = 0;
   4771     if (OMX_StateLoaded != m_state)
   4772     {
   4773         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
   4774                           m_state);
   4775         DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
   4776     }
   4777     else
   4778     {
   4779       DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
   4780     }
   4781 
   4782     /*Check if the output buffers have to be cleaned up*/
   4783     if(m_out_mem_ptr)
   4784     {
   4785         DEBUG_PRINT_LOW("Freeing the Output Memory\n");
   4786         for (i=0; i<m_out_buf_count; i++ )
   4787         {
   4788           free_output_buffer (&m_out_mem_ptr[i]);
   4789         }
   4790         if (driver_context.ptr_outputbuffer)
   4791         {
   4792           free (driver_context.ptr_outputbuffer);
   4793           driver_context.ptr_outputbuffer = NULL;
   4794         }
   4795 
   4796         if (driver_context.ptr_respbuffer)
   4797         {
   4798           free (driver_context.ptr_respbuffer);
   4799           driver_context.ptr_respbuffer = NULL;
   4800         }
   4801         free(m_out_mem_ptr);
   4802         m_out_mem_ptr = NULL;
   4803     }
   4804 
   4805     /*Check if the input buffers have to be cleaned up*/
   4806     if(m_inp_mem_ptr)
   4807     {
   4808         DEBUG_PRINT_LOW("Freeing the Input Memory\n");
   4809         for (i=0; i<m_inp_buf_count; i++ )
   4810         {
   4811           free_input_buffer (&m_inp_mem_ptr[i]);
   4812         }
   4813 
   4814         if (driver_context.ptr_inputbuffer)
   4815         {
   4816           free (driver_context.ptr_inputbuffer);
   4817           driver_context.ptr_inputbuffer = NULL;
   4818         }
   4819 
   4820         free(m_inp_mem_ptr);
   4821         m_inp_mem_ptr = NULL;
   4822     }
   4823 
   4824     if(h264_scratch.pBuffer)
   4825     {
   4826       free(h264_scratch.pBuffer);
   4827       h264_scratch.pBuffer = NULL;
   4828     }
   4829 
   4830     if(m_platform_list)
   4831     {
   4832         free(m_platform_list);
   4833         m_platform_list = NULL;
   4834     }
   4835     if(m_vendor_config.pData)
   4836     {
   4837         free(m_vendor_config.pData);
   4838         m_vendor_config.pData = NULL;
   4839     }
   4840 
   4841     // Reset counters in mesg queues
   4842     m_ftb_q.m_size=0;
   4843     m_cmd_q.m_size=0;
   4844     m_etb_q.m_size=0;
   4845     m_ftb_q.m_read = m_ftb_q.m_write =0;
   4846     m_cmd_q.m_read = m_cmd_q.m_write =0;
   4847     m_etb_q.m_read = m_etb_q.m_write =0;
   4848 
   4849     DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
   4850     (void)ioctl(driver_context.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   4851         NULL);
   4852     DEBUG_PRINT_HIGH("\n Close the driver instance");
   4853     close(driver_context.video_driver_fd);
   4854 
   4855 #if BITSTREAM_LOG
   4856     fclose (outputBufferFile1);
   4857 #endif
   4858 #ifdef _ANDROID_
   4859     //for (i=0; i<m_out_buf_count; i++ )
   4860     {
   4861        // Clear the strong reference
   4862       m_heap_ptr.clear();
   4863     }
   4864 #endif // _ANDROID_
   4865   DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
   4866   return OMX_ErrorNone;
   4867 }
   4868 
   4869 /* ======================================================================
   4870 FUNCTION
   4871   omx_vdec::UseEGLImage
   4872 
   4873 DESCRIPTION
   4874   OMX Use EGL Image method implementation <TBD>.
   4875 
   4876 PARAMETERS
   4877   <TBD>.
   4878 
   4879 RETURN VALUE
   4880   Not Implemented error.
   4881 
   4882 ========================================================================== */
   4883 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
   4884                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4885                                           OMX_IN OMX_U32                        port,
   4886                                           OMX_IN OMX_PTR                     appData,
   4887                                           OMX_IN void*                      eglImage)
   4888 {
   4889     DEBUG_PRINT_ERROR("Error : use_EGL_image:  Not Implemented \n");
   4890     return OMX_ErrorNotImplemented;
   4891 }
   4892 
   4893 /* ======================================================================
   4894 FUNCTION
   4895   omx_vdec::ComponentRoleEnum
   4896 
   4897 DESCRIPTION
   4898   OMX Component Role Enum method implementation.
   4899 
   4900 PARAMETERS
   4901   <TBD>.
   4902 
   4903 RETURN VALUE
   4904   OMX Error None if everything is successful.
   4905 ========================================================================== */
   4906 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   4907                                                 OMX_OUT OMX_U8*        role,
   4908                                                 OMX_IN OMX_U32        index)
   4909 {
   4910   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4911 
   4912   if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
   4913   {
   4914     if((0 == index) && role)
   4915     {
   4916       strncpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   4917       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   4918     }
   4919     else
   4920     {
   4921       eRet = OMX_ErrorNoMore;
   4922     }
   4923   }
   4924   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
   4925   {
   4926     if((0 == index) && role)
   4927     {
   4928       strncpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   4929       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   4930     }
   4931     else
   4932     {
   4933       DEBUG_PRINT_LOW("\n No more roles \n");
   4934       eRet = OMX_ErrorNoMore;
   4935     }
   4936   }
   4937   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
   4938   {
   4939     if((0 == index) && role)
   4940     {
   4941       strncpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   4942       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   4943     }
   4944     else
   4945     {
   4946       DEBUG_PRINT_LOW("\n No more roles \n");
   4947       eRet = OMX_ErrorNoMore;
   4948     }
   4949   }
   4950   else if(!strncmp(driver_context.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
   4951   {
   4952     if((0 == index) && role)
   4953     {
   4954       strncpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   4955       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   4956     }
   4957     else
   4958     {
   4959       DEBUG_PRINT_LOW("\n No more roles \n");
   4960       eRet = OMX_ErrorNoMore;
   4961     }
   4962   }
   4963   else
   4964   {
   4965     DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
   4966     eRet = OMX_ErrorInvalidComponentName;
   4967   }
   4968   return eRet;
   4969 }
   4970 
   4971 
   4972 
   4973 
   4974 /* ======================================================================
   4975 FUNCTION
   4976   omx_vdec::AllocateDone
   4977 
   4978 DESCRIPTION
   4979   Checks if entire buffer pool is allocated by IL Client or not.
   4980   Need this to move to IDLE state.
   4981 
   4982 PARAMETERS
   4983   None.
   4984 
   4985 RETURN VALUE
   4986   true/false.
   4987 
   4988 ========================================================================== */
   4989 bool omx_vdec::allocate_done(void)
   4990 {
   4991   bool bRet = false;
   4992   bool bRet_In = false;
   4993   bool bRet_Out = false;
   4994 
   4995   bRet_In = allocate_input_done();
   4996   bRet_Out = allocate_output_done();
   4997 
   4998   if(bRet_In && bRet_Out)
   4999   {
   5000       bRet = true;
   5001   }
   5002 
   5003   return bRet;
   5004 }
   5005 /* ======================================================================
   5006 FUNCTION
   5007   omx_vdec::AllocateInputDone
   5008 
   5009 DESCRIPTION
   5010   Checks if I/P buffer pool is allocated by IL Client or not.
   5011 
   5012 PARAMETERS
   5013   None.
   5014 
   5015 RETURN VALUE
   5016   true/false.
   5017 
   5018 ========================================================================== */
   5019 bool omx_vdec::allocate_input_done(void)
   5020 {
   5021   bool bRet = false;
   5022   unsigned i=0;
   5023 
   5024   if (m_inp_mem_ptr == NULL)
   5025   {
   5026       return bRet;
   5027   }
   5028   if(m_inp_mem_ptr )
   5029   {
   5030     for(;i<m_inp_buf_count;i++)
   5031     {
   5032       if(BITMASK_ABSENT(&m_inp_bm_count,i))
   5033       {
   5034         break;
   5035       }
   5036     }
   5037   }
   5038   if(i==m_inp_buf_count)
   5039   {
   5040     bRet = true;
   5041     DEBUG_PRINT_HIGH("\n Allocate done for all i/p buffers");
   5042   }
   5043   if(i==m_inp_buf_count && m_inp_bEnabled)
   5044   {
   5045      m_inp_bPopulated = OMX_TRUE;
   5046   }
   5047   return bRet;
   5048 }
   5049 /* ======================================================================
   5050 FUNCTION
   5051   omx_vdec::AllocateOutputDone
   5052 
   5053 DESCRIPTION
   5054   Checks if entire O/P buffer pool is allocated by IL Client or not.
   5055 
   5056 PARAMETERS
   5057   None.
   5058 
   5059 RETURN VALUE
   5060   true/false.
   5061 
   5062 ========================================================================== */
   5063 bool omx_vdec::allocate_output_done(void)
   5064 {
   5065   bool bRet = false;
   5066   unsigned j=0;
   5067 
   5068   if (m_out_mem_ptr == NULL)
   5069   {
   5070       return bRet;
   5071   }
   5072 
   5073   if(m_out_mem_ptr )
   5074   {
   5075     for(;j<m_out_buf_count;j++)
   5076     {
   5077       if(BITMASK_ABSENT(&m_out_bm_count,j))
   5078       {
   5079         break;
   5080       }
   5081     }
   5082   }
   5083 
   5084   if(j==m_out_buf_count)
   5085   {
   5086     bRet = true;
   5087     DEBUG_PRINT_HIGH("\n Allocate done for all o/p buffers");
   5088   }
   5089 
   5090   if(j==m_out_buf_count && m_out_bEnabled)
   5091   {
   5092      m_out_bPopulated = OMX_TRUE;
   5093   }
   5094   return bRet;
   5095 }
   5096 
   5097 /* ======================================================================
   5098 FUNCTION
   5099   omx_vdec::ReleaseDone
   5100 
   5101 DESCRIPTION
   5102   Checks if IL client has released all the buffers.
   5103 
   5104 PARAMETERS
   5105   None.
   5106 
   5107 RETURN VALUE
   5108   true/false
   5109 
   5110 ========================================================================== */
   5111 bool omx_vdec::release_done(void)
   5112 {
   5113   bool bRet = false;
   5114 
   5115   if(release_input_done())
   5116   {
   5117     if(release_output_done())
   5118     {
   5119         bRet = true;
   5120     }
   5121   }
   5122   return bRet;
   5123 }
   5124 
   5125 
   5126 /* ======================================================================
   5127 FUNCTION
   5128   omx_vdec::ReleaseOutputDone
   5129 
   5130 DESCRIPTION
   5131   Checks if IL client has released all the buffers.
   5132 
   5133 PARAMETERS
   5134   None.
   5135 
   5136 RETURN VALUE
   5137   true/false
   5138 
   5139 ========================================================================== */
   5140 bool omx_vdec::release_output_done(void)
   5141 {
   5142   bool bRet = false;
   5143   unsigned i=0,j=0;
   5144 
   5145   DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
   5146   if(m_out_mem_ptr)
   5147   {
   5148       for(;j<m_out_buf_count;j++)
   5149       {
   5150         if(BITMASK_PRESENT(&m_out_bm_count,j))
   5151         {
   5152           break;
   5153         }
   5154       }
   5155     if(j==m_out_buf_count)
   5156     {
   5157       m_out_bm_count = 0;
   5158       bRet = true;
   5159     }
   5160   }
   5161   else
   5162   {
   5163     m_out_bm_count = 0;
   5164     bRet = true;
   5165   }
   5166   return bRet;
   5167 }
   5168 /* ======================================================================
   5169 FUNCTION
   5170   omx_vdec::ReleaseInputDone
   5171 
   5172 DESCRIPTION
   5173   Checks if IL client has released all the buffers.
   5174 
   5175 PARAMETERS
   5176   None.
   5177 
   5178 RETURN VALUE
   5179   true/false
   5180 
   5181 ========================================================================== */
   5182 bool omx_vdec::release_input_done(void)
   5183 {
   5184   bool bRet = false;
   5185   unsigned i=0,j=0;
   5186 
   5187   DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   5188   if(m_inp_mem_ptr)
   5189   {
   5190       for(;j<m_inp_buf_count;j++)
   5191       {
   5192         if( BITMASK_PRESENT(&m_inp_bm_count,j))
   5193         {
   5194           break;
   5195         }
   5196       }
   5197     if(j==m_inp_buf_count)
   5198     {
   5199       bRet = true;
   5200     }
   5201   }
   5202   else
   5203   {
   5204     bRet = true;
   5205   }
   5206   return bRet;
   5207 }
   5208 
   5209 /* ======================================================================
   5210 FUNCTION
   5211   omx_vdec::omx_vdec_check_port_settings
   5212 
   5213 DESCRIPTION
   5214   Parse meta data to check the height and width param
   5215   Check the level and profile
   5216 
   5217 PARAMETERS
   5218   None.
   5219 
   5220 RETURN VALUE
   5221   OMX_ErrorNone, if profile and level are supported
   5222   OMX_ErrorUnsupportedSetting, if profile and level are not supported
   5223 ========================================================================== */
   5224 OMX_ERRORTYPE omx_vdec::omx_vdec_check_port_settings(bool *port_setting_changed)
   5225 {
   5226     struct vdec_ioctl_msg ioctl_msg;
   5227     unsigned int alignment = 0,buffer_size = 0;
   5228     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5229 
   5230     *port_setting_changed = false;
   5231     ioctl_msg.inputparam = NULL;
   5232     ioctl_msg.outputparam = &driver_context.video_resoultion;
   5233     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_PICRES,&ioctl_msg))
   5234     {
   5235       DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_PICRES in port_setting");
   5236       return OMX_ErrorHardware;
   5237     }
   5238 
   5239     ioctl_msg.inputparam = NULL;
   5240     ioctl_msg.outputparam = &driver_context.output_buffer;
   5241     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_GET_BUFFER_REQ,
   5242                &ioctl_msg))
   5243     {
   5244       DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
   5245       return OMX_ErrorHardware;
   5246     }
   5247     DEBUG_PRINT_HIGH("\n Queried Dimensions H=%d W=%d Act H=%d W=%d",
   5248                        driver_context.video_resoultion.frame_height,
   5249                        driver_context.video_resoultion.frame_width,
   5250                        m_height,m_width);
   5251     DEBUG_PRINT_HIGH("\n Queried Buffer ACnt=%d BSiz=%d Act Acnt=%d Bsiz=%d",
   5252                        driver_context.output_buffer.actualcount,
   5253                        driver_context.output_buffer.buffer_size,
   5254                        m_out_buf_count,m_out_buf_size);
   5255 
   5256     DEBUG_PRINT_HIGH("\n Queried stride cuur Str=%d cur scan=%d Act str=%d act scan =%d",
   5257                        driver_context.video_resoultion.stride,driver_context.video_resoultion.scan_lines,
   5258                        stride,scan_lines);
   5259 
   5260 
   5261     if(driver_context.video_resoultion.frame_height != m_height ||
   5262        driver_context.video_resoultion.frame_width != m_width ||
   5263        driver_context.video_resoultion.scan_lines != scan_lines ||
   5264        driver_context.video_resoultion.stride != stride ||
   5265        driver_context.output_buffer.actualcount != m_out_buf_count ||
   5266        driver_context.output_buffer.buffer_size > m_out_buf_size)
   5267     {
   5268       *port_setting_changed = true;
   5269       ioctl_msg.inputparam = &driver_context.output_buffer;
   5270       ioctl_msg.outputparam = NULL;
   5271 
   5272       if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER_REQ,
   5273                  &ioctl_msg))
   5274       {
   5275          DEBUG_PRINT_ERROR("\n Error in VDEC_IOCTL_GET_BUFFER_REQ in port_setting");
   5276          return OMX_ErrorHardware;
   5277       }
   5278       m_out_buf_size_recon = driver_context.output_buffer.buffer_size;
   5279       m_out_buf_count_recon = driver_context.output_buffer.actualcount;
   5280       m_out_buf_count_min_recon = driver_context.output_buffer.mincount;
   5281 
   5282       alignment = driver_context.output_buffer.alignment;
   5283       buffer_size = driver_context.output_buffer.buffer_size;
   5284       m_out_buf_size_recon =
   5285         ((buffer_size + alignment - 1) & (~(alignment - 1)));
   5286       m_crop_dy = m_height      = driver_context.video_resoultion.frame_height;
   5287       m_crop_dx = m_width       = driver_context.video_resoultion.frame_width;
   5288       scan_lines = driver_context.video_resoultion.scan_lines;
   5289       stride = driver_context.video_resoultion.stride;
   5290       m_port_height             = m_height;
   5291       m_port_width              = m_width;
   5292     }
   5293 
   5294     return eRet;
   5295 }
   5296 
   5297 
   5298 /* ======================================================================
   5299 FUNCTION
   5300   omx_vdec::omx_vdec_validate_port_param
   5301 
   5302 DESCRIPTION
   5303   Get the PMEM area from video decoder
   5304 
   5305 PARAMETERS
   5306   None.
   5307 
   5308 RETURN VALUE
   5309   None
   5310 ========================================================================== */
   5311 OMX_ERRORTYPE omx_vdec::omx_vdec_validate_port_param(int height, int width)
   5312 {
   5313     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5314     long hxw = height*width;
   5315     long lmt_hxw = 0;
   5316 
   5317     return ret;
   5318 }
   5319 
   5320 static FILE * outputBufferFile = NULL;
   5321 
   5322 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   5323                                OMX_BUFFERHEADERTYPE * buffer)
   5324 {
   5325   OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   5326 
   5327   if (buffer == NULL || ((buffer - m_out_mem_ptr) > m_out_buf_count))
   5328   {
   5329      return OMX_ErrorBadParameter;
   5330   }
   5331 
   5332   DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   5333       buffer, buffer->pBuffer);
   5334   pending_output_buffers --;
   5335 
   5336   if (buffer->nFlags & 0x01)
   5337   {
   5338     DEBUG_PRINT_LOW("\n Output EOS has been reached");
   5339 
   5340     m_outeos_reached = 0;
   5341     m_ineos_reached = 0;
   5342     h264_scratch.nFilledLen = 0;
   5343     nal_count = 0;
   5344     look_ahead_nal = false;
   5345     frame_count = 0;
   5346 
   5347     if (m_frame_parser.mutils)
   5348     {
   5349       m_frame_parser.mutils->initialize_frame_checking_environment();
   5350     }
   5351     if (psource_frame)
   5352     {
   5353       m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   5354       psource_frame = NULL;
   5355     }
   5356 
   5357     if (pdest_frame)
   5358     {
   5359       pdest_frame->nFilledLen = 0;
   5360       m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
   5361       pdest_frame = NULL;
   5362     }
   5363     m_frame_parser.flush();
   5364   }
   5365 
   5366   DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
   5367 
   5368   if (outputBufferFile == NULL)
   5369   {
   5370     outputBufferFile = fopen ("/data/output.yuv","wb");
   5371   }
   5372   if (outputBufferFile)
   5373   {
   5374     /*fwrite (buffer->pBuffer,1,buffer->nFilledLen,
   5375                   outputBufferFile); */
   5376   }
   5377   /* For use buffer we need to copy the data */
   5378   if (m_cb.FillBufferDone)
   5379   {
   5380     pPMEMInfo  = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   5381                    ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   5382                       buffer->pPlatformPrivate)->entryList->entry;
   5383     DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
   5384     m_cb.FillBufferDone (hComp,m_app_data,buffer);
   5385     DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
   5386   }
   5387   else
   5388   {
   5389     return OMX_ErrorBadParameter;
   5390   }
   5391 
   5392   return OMX_ErrorNone;
   5393 }
   5394 
   5395 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   5396                                           OMX_BUFFERHEADERTYPE* buffer)
   5397 {
   5398 
   5399     if (buffer == NULL || ((buffer - m_inp_mem_ptr) > m_inp_buf_count))
   5400     {
   5401        return OMX_ErrorBadParameter;
   5402     }
   5403 
   5404     DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   5405         buffer, buffer->pBuffer);
   5406     pending_input_buffers--;
   5407 
   5408     if (arbitrary_bytes)
   5409     {
   5410       if (pdest_frame == NULL && input_flush_progress == false)
   5411       {
   5412         DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
   5413         pdest_frame = buffer;
   5414         buffer->nFilledLen = 0;
   5415         push_input_buffer (hComp);
   5416       }
   5417       else
   5418       {
   5419         DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
   5420         buffer->nFilledLen = 0;
   5421         if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL))
   5422         {
   5423           DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
   5424         }
   5425       }
   5426     }
   5427     else if(m_cb.EmptyBufferDone)
   5428     {
   5429         buffer->nFilledLen = 0;
   5430         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   5431     }
   5432     return OMX_ErrorNone;
   5433 }
   5434 
   5435 
   5436 int omx_vdec::async_message_process (void *context, void* message)
   5437 {
   5438   omx_vdec* omx = NULL;
   5439   struct vdec_msginfo *vdec_msg = NULL;
   5440   OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   5441   struct vdec_output_frameinfo *output_respbuf = NULL;
   5442 
   5443   if (context == NULL || message == NULL)
   5444   {
   5445     DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
   5446     return -1;
   5447   }
   5448   vdec_msg = (struct vdec_msginfo *)message;
   5449 
   5450   omx = reinterpret_cast<omx_vdec*>(context);
   5451   switch (vdec_msg->msgcode)
   5452   {
   5453 
   5454   case VDEC_MSG_EVT_HW_ERROR:
   5455     omx->post_event (NULL,vdec_msg->status_code,\
   5456                      OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   5457   break;
   5458 
   5459   case VDEC_MSG_RESP_START_DONE:
   5460     omx->post_event (NULL,vdec_msg->status_code,\
   5461                      OMX_COMPONENT_GENERATE_START_DONE);
   5462   break;
   5463 
   5464   case VDEC_MSG_RESP_STOP_DONE:
   5465     omx->post_event (NULL,vdec_msg->status_code,\
   5466                      OMX_COMPONENT_GENERATE_STOP_DONE);
   5467   break;
   5468 
   5469   case VDEC_MSG_RESP_RESUME_DONE:
   5470     omx->post_event (NULL,vdec_msg->status_code,\
   5471                      OMX_COMPONENT_GENERATE_RESUME_DONE);
   5472   break;
   5473 
   5474   case VDEC_MSG_RESP_PAUSE_DONE:
   5475     omx->post_event (NULL,vdec_msg->status_code,\
   5476                      OMX_COMPONENT_GENERATE_PAUSE_DONE);
   5477   break;
   5478 
   5479   case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   5480     omx->post_event (NULL,vdec_msg->status_code,\
   5481                      OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   5482     break;
   5483   case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   5484     omx->post_event (NULL,vdec_msg->status_code,\
   5485                      OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   5486     break;
   5487   case VDEC_MSG_RESP_INPUT_FLUSHED:
   5488   case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   5489 
   5490     omxhdr = (OMX_BUFFERHEADERTYPE* )\
   5491               vdec_msg->msgdata.input_frame_clientdata;
   5492 
   5493 
   5494     if (omxhdr == NULL ||
   5495        ((omxhdr - omx->m_inp_mem_ptr) > omx->m_inp_buf_count) )
   5496     {
   5497        omxhdr = NULL;
   5498        vdec_msg->status_code = VDEC_S_EFATAL;
   5499     }
   5500 
   5501     omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
   5502                      OMX_COMPONENT_GENERATE_EBD);
   5503     break;
   5504   case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   5505   case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   5506     omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data;
   5507     DEBUG_PRINT_LOW("\n Got Buffer back from Driver %p omxhdr time stamp = %d " ,omxhdr,vdec_msg->msgdata.output_frame.time_stamp);
   5508 
   5509     if  ( (omxhdr != NULL) &&
   5510          ((omxhdr - omx->m_out_mem_ptr)  < omx->m_out_buf_count) &&
   5511          (omxhdr->pOutputPortPrivate != NULL) &&
   5512          ( ((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   5513              - omx->driver_context.ptr_respbuffer) < omx->m_out_buf_count)
   5514          )
   5515     {
   5516       if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen)
   5517       {
   5518         omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   5519         omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   5520         omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   5521         omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags & 0x01);
   5522 
   5523         output_respbuf = (struct vdec_output_frameinfo *)\
   5524                           omxhdr->pOutputPortPrivate;
   5525         output_respbuf->framesize.bottom = \
   5526           vdec_msg->msgdata.output_frame.framesize.bottom;
   5527         output_respbuf->framesize.left = \
   5528           vdec_msg->msgdata.output_frame.framesize.left;
   5529         output_respbuf->framesize.right = \
   5530           vdec_msg->msgdata.output_frame.framesize.right;
   5531         output_respbuf->framesize.top = \
   5532           vdec_msg->msgdata.output_frame.framesize.top;
   5533         output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   5534         output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   5535         output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp;
   5536         output_respbuf->flags = vdec_msg->msgdata.output_frame.flags;
   5537 
   5538         /*Use buffer case*/
   5539         if (omx->output_use_buffer)
   5540         {
   5541           if (vdec_msg->msgdata.output_frame.len <= omxhdr->nAllocLen)
   5542           {
   5543             memcpy ( omxhdr->pBuffer,
   5544                      (vdec_msg->msgdata.output_frame.bufferaddr +
   5545                       vdec_msg->msgdata.output_frame.offset),
   5546                       vdec_msg->msgdata.output_frame.len );
   5547           }
   5548           else
   5549           {
   5550             omxhdr->nFilledLen = 0;
   5551           }
   5552         }
   5553       }
   5554       else
   5555       {
   5556         omxhdr->nFilledLen = 0;
   5557       }
   5558 
   5559     }
   5560     else
   5561     {
   5562        omxhdr = NULL;
   5563        vdec_msg->status_code = VDEC_S_EFATAL;
   5564     }
   5565 
   5566     DEBUG_PRINT_LOW("\n Driver returned a output Buffer status %d",
   5567                        vdec_msg->status_code);
   5568     omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
   5569                      OMX_COMPONENT_GENERATE_FBD);
   5570     break;
   5571   default:
   5572     break;
   5573   }
   5574   return 1;
   5575 }
   5576 
   5577 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   5578                                                    OMX_HANDLETYPE hComp,
   5579                                                    OMX_BUFFERHEADERTYPE *buffer
   5580                                                            )
   5581 {
   5582   unsigned address,p2,id;
   5583   DEBUG_PRINT_LOW("\n Empty this arbitrary");
   5584 
   5585   if (buffer == NULL)
   5586   {
   5587     return OMX_ErrorBadParameter;
   5588   }
   5589   DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   5590   DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
   5591         buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
   5592 
   5593   if( input_flush_progress == true || m_ineos_reached == 1)
   5594   {
   5595     DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
   5596     m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   5597     return OMX_ErrorNone;
   5598   }
   5599 
   5600   if (psource_frame == NULL)
   5601   {
   5602     DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
   5603     psource_frame = buffer;
   5604     DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
   5605     push_input_buffer (hComp);
   5606   }
   5607   else
   5608   {
   5609     DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
   5610     if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL))
   5611     {
   5612       return OMX_ErrorBadParameter;
   5613     }
   5614   }
   5615 
   5616 
   5617   return OMX_ErrorNone;
   5618 }
   5619 
   5620 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   5621 {
   5622   unsigned address,p2,id;
   5623   OMX_ERRORTYPE ret = OMX_ErrorNone;
   5624 
   5625   if (pdest_frame == NULL || psource_frame == NULL)
   5626   {
   5627     /*Check if we have a destination buffer*/
   5628     if (pdest_frame == NULL)
   5629     {
   5630       DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
   5631       if (m_input_free_q.m_size && !gate_input_buffers)
   5632       {
   5633         m_input_free_q.pop_entry(&address,&p2,&id);
   5634         pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   5635         pdest_frame->nFilledLen = 0;
   5636         DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
   5637       }
   5638     }
   5639 
   5640     /*Check if we have a destination buffer*/
   5641     if (psource_frame == NULL)
   5642     {
   5643       DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
   5644       if (m_input_pending_q.m_size && !gate_input_buffers)
   5645       {
   5646         m_input_pending_q.pop_entry(&address,&p2,&id);
   5647         psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   5648         DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
   5649                 psource_frame->nTimeStamp);
   5650         DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
   5651         psource_frame->nFlags,psource_frame->nFilledLen);
   5652 
   5653       }
   5654     }
   5655 
   5656   }
   5657 
   5658   while ((pdest_frame != NULL) && (psource_frame != NULL)&& !gate_input_buffers)
   5659   {
   5660     switch (codec_type_parse)
   5661     {
   5662       case CODEC_TYPE_MPEG4:
   5663       case CODEC_TYPE_H263:
   5664         ret =  push_input_sc_codec(hComp);
   5665       break;
   5666       case CODEC_TYPE_H264:
   5667         ret = push_input_h264(hComp);
   5668       break;
   5669       case CODEC_TYPE_VC1:
   5670         ret = push_input_vc1(hComp);
   5671       break;
   5672     }
   5673     if (ret != OMX_ErrorNone)
   5674     {
   5675       DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
   5676       omx_report_error ();
   5677       break;
   5678     }
   5679   }
   5680 
   5681   return ret;
   5682 }
   5683 
   5684 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   5685 {
   5686   OMX_U32 partial_frame = 1;
   5687   OMX_BOOL genarte_edb = OMX_TRUE,generate_eos = OMX_TRUE;
   5688   unsigned address,p2,id;
   5689 
   5690   DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %d",
   5691         psource_frame,psource_frame->nTimeStamp);
   5692   if (m_frame_parser.parse_mpeg4_frame(psource_frame,
   5693                                        pdest_frame,&partial_frame) == -1)
   5694   {
   5695     DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
   5696     return OMX_ErrorBadParameter;
   5697   }
   5698 
   5699   if (partial_frame == 0)
   5700   {
   5701     DEBUG_PRINT_LOW("\n Frame size %d source %p frame count %d",
   5702           pdest_frame->nFilledLen,psource_frame,frame_count);
   5703 
   5704 
   5705     DEBUG_PRINT_LOW("\n TimeStamp updated %d",pdest_frame->nTimeStamp);
   5706     /*First Parsed buffer will have only header Hence skip*/
   5707     if (frame_count == 0)
   5708     {
   5709       DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
   5710       mp4h263_flags = psource_frame->nFlags;
   5711       mp4h263_timestamp = psource_frame->nTimeStamp;
   5712       frame_count++;
   5713     }
   5714     else
   5715     {
   5716       pdest_frame->nTimeStamp = mp4h263_timestamp;
   5717       mp4h263_timestamp = psource_frame->nTimeStamp;
   5718       pdest_frame->nFlags = mp4h263_flags;
   5719       mp4h263_flags  = psource_frame->nFlags;
   5720 
   5721       if(psource_frame->nFilledLen == 0)
   5722       {
   5723         pdest_frame->nFlags = mp4h263_flags;
   5724         generate_eos = OMX_FALSE;
   5725       }
   5726 
   5727 
   5728       /*Push the frame to the Decoder*/
   5729       if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
   5730       {
   5731         return OMX_ErrorBadParameter;
   5732       }
   5733       if(m_event_port_settings_sent)
   5734       {
   5735         gate_input_buffers = true;
   5736         return OMX_ErrorNone;
   5737       }
   5738       frame_count++;
   5739       pdest_frame = NULL;
   5740 
   5741       if (m_input_free_q.m_size && !gate_input_buffers)
   5742       {
   5743         m_input_free_q.pop_entry(&address,&p2,&id);
   5744         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   5745         pdest_frame->nFilledLen = 0;
   5746       }
   5747     }
   5748   }
   5749   else
   5750   {
   5751     DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
   5752     /*Check if Destination Buffer is full*/
   5753     if (pdest_frame->nAllocLen ==
   5754         pdest_frame->nFilledLen + pdest_frame->nOffset)
   5755     {
   5756       DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
   5757       return OMX_ErrorStreamCorrupt;
   5758     }
   5759   }
   5760 
   5761   if (psource_frame->nFilledLen == 0)
   5762   {
   5763     if ((psource_frame->nFlags & 0x01) && generate_eos)
   5764     {
   5765       if (pdest_frame)
   5766       {
   5767         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   5768         pdest_frame->nFlags = psource_frame->nFlags;
   5769         DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
   5770                      pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   5771         DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
   5772                      pdest_frame->nFilledLen,frame_count++);
   5773         /*Push the frame to the Decoder*/
   5774         if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
   5775         {
   5776           return OMX_ErrorBadParameter;
   5777         }
   5778         frame_count++;
   5779         pdest_frame = NULL;
   5780       }
   5781       else
   5782       {
   5783         DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
   5784         genarte_edb = OMX_FALSE;
   5785       }
   5786    }
   5787     if(genarte_edb)
   5788     {
   5789       DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
   5790       m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   5791       psource_frame = NULL;
   5792 
   5793       if (m_input_pending_q.m_size)
   5794       {
   5795         DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
   5796         m_input_pending_q.pop_entry(&address,&p2,&id);
   5797         psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   5798         DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %d",psource_frame,
   5799                 psource_frame->nTimeStamp);
   5800         DEBUG_PRINT_LOW("\n Next source Buffer flag %d length %d",
   5801         psource_frame->nFlags,psource_frame->nFilledLen);
   5802       }
   5803     }
   5804    }
   5805   return OMX_ErrorNone;
   5806 }
   5807 
   5808 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   5809 {
   5810   OMX_U32 partial_frame = 1;
   5811   unsigned address,p2,id;
   5812   OMX_BOOL isNewFrame = OMX_FALSE;
   5813   OMX_BOOL genarte_edb = OMX_TRUE;
   5814   OMX_BOOL skip_parsing = OMX_FALSE;
   5815 
   5816   if (h264_scratch.pBuffer == NULL)
   5817   {
   5818     DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
   5819     return OMX_ErrorBadParameter;
   5820   }
   5821   DEBUG_PRINT_LOW("\n Values of h264_scratch.nFilledLen %d look_ahead_nal %d",
   5822                     h264_scratch.nFilledLen,look_ahead_nal);
   5823   DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
   5824   if (h264_scratch.nFilledLen && look_ahead_nal)
   5825   {
   5826     look_ahead_nal = false;
   5827     DEBUG_PRINT_LOW("\n Copy the previous NAL into Buffer %d ",
   5828                        h264_scratch.nFilledLen);
   5829     if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   5830          h264_scratch.nFilledLen)
   5831     {
   5832       memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   5833               h264_scratch.pBuffer,h264_scratch.nFilledLen);
   5834       pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   5835       DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen);
   5836       h264_scratch.nFilledLen = 0;
   5837     }
   5838     else
   5839     {
   5840       DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
   5841       return OMX_ErrorBadParameter;
   5842     }
   5843   }
   5844 
   5845   if(psource_frame->nFlags & 0x01)
   5846   {
   5847     DEBUG_PRINT_LOW("\n EOS has been reached no parsing required");
   5848     skip_parsing = OMX_TRUE;
   5849     if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   5850          psource_frame->nFilledLen)
   5851     {
   5852       memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   5853               (psource_frame->pBuffer+psource_frame->nOffset),
   5854               psource_frame->nFilledLen);
   5855       pdest_frame->nFilledLen += psource_frame->nFilledLen;
   5856       DEBUG_PRINT_LOW("\n Total filled length %d",pdest_frame->nFilledLen);
   5857       psource_frame->nFilledLen = 0;
   5858     }
   5859     else
   5860     {
   5861       DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
   5862       return OMX_ErrorBadParameter;
   5863     }
   5864   }
   5865 
   5866   if(!skip_parsing)
   5867   {
   5868     if (nal_length == 0)
   5869     {
   5870       DEBUG_PRINT_LOW("\n NAL length Zero hence parse using start code");
   5871       if (m_frame_parser.parse_mpeg4_frame(psource_frame,
   5872           &h264_scratch,&partial_frame) == -1)
   5873       {
   5874         DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
   5875         return OMX_ErrorBadParameter;
   5876       }
   5877     }
   5878     else
   5879     {
   5880       DEBUG_PRINT_LOW("\n NAL length %d hence parse with NAL length %d",nal_length);
   5881       if (m_frame_parser.parse_h264_nallength(psource_frame,
   5882           &h264_scratch,&partial_frame) == -1)
   5883       {
   5884         DEBUG_PRINT_ERROR("\n Error In Parsing NAL Return Error");
   5885         return OMX_ErrorBadParameter;
   5886       }
   5887     }
   5888 
   5889     if (partial_frame == 0)
   5890     {
   5891 
   5892       if (nal_count == 0 && h264_scratch.nFilledLen == 0)
   5893       {
   5894         DEBUG_PRINT_LOW("\n First NAL with Zero Length Hence Skip");
   5895         nal_count++;
   5896         h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   5897         h264_scratch.nFlags = psource_frame->nFlags;
   5898       }
   5899       else
   5900       {
   5901         DEBUG_PRINT_LOW("\n Length of New NAL is %d",h264_scratch.nFilledLen);
   5902 
   5903         m_frame_parser.mutils->isNewFrame(h264_scratch.pBuffer,
   5904             h264_scratch.nFilledLen,0,isNewFrame);
   5905         nal_count++;
   5906 
   5907         if (!isNewFrame)
   5908         {
   5909           if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   5910               h264_scratch.nFilledLen)
   5911           {
   5912             DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %d",
   5913                 h264_scratch.nFilledLen);
   5914             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   5915                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   5916             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   5917             h264_scratch.nFilledLen = 0;
   5918           }
   5919           else
   5920           {
   5921             DEBUG_PRINT_LOW("\n Destination buffer overflow for H264");
   5922             return OMX_ErrorBadParameter;
   5923           }
   5924         }
   5925         else
   5926         {
   5927           look_ahead_nal = true;
   5928           pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   5929           pdest_frame->nFlags = h264_scratch.nFlags;
   5930           h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   5931           h264_scratch.nFlags = psource_frame->nFlags;
   5932 
   5933           DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
   5934                        pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   5935           DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
   5936                        pdest_frame->nFilledLen,frame_count++);
   5937 
   5938           if (pdest_frame->nFilledLen == 0)
   5939           {
   5940             DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
   5941             look_ahead_nal = false;
   5942             if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   5943                  h264_scratch.nFilledLen)
   5944             {
   5945               memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   5946                       h264_scratch.pBuffer,h264_scratch.nFilledLen);
   5947               pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   5948               h264_scratch.nFilledLen = 0;
   5949             }
   5950             else
   5951             {
   5952               DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
   5953               return OMX_ErrorBadParameter;
   5954             }
   5955           }
   5956           else
   5957           {
   5958             /*Push the frame to the Decoder*/
   5959             if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
   5960             {
   5961               return OMX_ErrorBadParameter;
   5962             }
   5963             if(m_event_port_settings_sent)
   5964             {
   5965               gate_input_buffers = true;
   5966               return OMX_ErrorNone;
   5967             }
   5968             //frame_count++;
   5969             pdest_frame = NULL;
   5970             if (m_input_free_q.m_size && !gate_input_buffers)
   5971             {
   5972               m_input_free_q.pop_entry(&address,&p2,&id);
   5973               pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   5974               DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
   5975               pdest_frame->nFilledLen = 0;
   5976             }
   5977           }
   5978         }
   5979       }
   5980     }
   5981     else
   5982     {
   5983       DEBUG_PRINT_LOW("\n Not a Complete Frame %d",pdest_frame->nFilledLen);
   5984       /*Check if Destination Buffer is full*/
   5985       if (h264_scratch.nAllocLen ==
   5986           h264_scratch.nFilledLen + h264_scratch.nOffset)
   5987       {
   5988         DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
   5989         return OMX_ErrorStreamCorrupt;
   5990       }
   5991     }
   5992   }
   5993 
   5994   if (psource_frame->nFilledLen == 0)
   5995   {
   5996     DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
   5997 
   5998     if (psource_frame->nFlags & 0x01)
   5999     {
   6000       if (pdest_frame)
   6001       {
   6002         DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
   6003         if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   6004              h264_scratch.nFilledLen)
   6005         {
   6006           memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   6007                   h264_scratch.pBuffer,h264_scratch.nFilledLen);
   6008           pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   6009           h264_scratch.nFilledLen = 0;
   6010         }
   6011         else
   6012         {
   6013           DEBUG_PRINT_ERROR("\nERROR:Destination buffer overflow for H264");
   6014           return OMX_ErrorBadParameter;
   6015         }
   6016         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   6017         pdest_frame->nFlags = psource_frame->nFlags;
   6018 
   6019         DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%d TimeStamp = %x",
   6020                      pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   6021         DEBUG_PRINT_LOW("\n Found a frame size = %d number = %d",
   6022                      pdest_frame->nFilledLen,frame_count++);
   6023         /*Push the frame to the Decoder*/
   6024         if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone)
   6025         {
   6026           return OMX_ErrorBadParameter;
   6027         }
   6028           if(m_event_port_settings_sent)
   6029           {
   6030             gate_input_buffers = true;
   6031             return OMX_ErrorNone;
   6032           }
   6033         frame_count++;
   6034         pdest_frame = NULL;
   6035       }
   6036       else
   6037       {
   6038         DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %d",
   6039                      pdest_frame,h264_scratch.nFilledLen);
   6040         genarte_edb = OMX_FALSE;
   6041       }
   6042     }
   6043     if(genarte_edb)
   6044     {
   6045 		m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   6046 		psource_frame = NULL;
   6047 		if (m_input_pending_q.m_size && !gate_input_buffers)
   6048 		{
   6049 			DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
   6050 		  m_input_pending_q.pop_entry(&address,&p2,&id);
   6051 		  psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   6052 		  DEBUG_PRINT_LOW("\nNext source Buffer flag %d length %d",
   6053 		  psource_frame->nFlags,psource_frame->nFilledLen);
   6054 		}
   6055 	}
   6056   }
   6057   return OMX_ErrorNone;
   6058 }
   6059 
   6060 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
   6061 {
   6062     OMX_U8 *buf, *pdest;
   6063     OMX_U32 partial_frame = 1;
   6064     OMX_U32 buf_len, dest_len;
   6065 
   6066     if(frame_count == 0)
   6067     {
   6068         DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
   6069         if(!m_vendor_config.pData)
   6070         {
   6071             DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
   6072             buf = psource_frame->pBuffer;
   6073             buf_len = psource_frame->nFilledLen;
   6074 
   6075             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   6076                 VC1_SP_MP_START_CODE)
   6077             {
   6078                 m_vc1_profile = VC1_SP_MP_RCV;
   6079             }
   6080             else if(*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE)
   6081             {
   6082                 m_vc1_profile = VC1_AP;
   6083             }
   6084             else
   6085             {
   6086                 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
   6087                 return OMX_ErrorStreamCorrupt;
   6088             }
   6089         }
   6090         else
   6091         {
   6092             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   6093                 pdest_frame->nOffset;
   6094             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   6095                 pdest_frame->nOffset);
   6096 
   6097             if(dest_len < m_vendor_config.nDataSize)
   6098             {
   6099                 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
   6100                 return OMX_ErrorBadParameter;
   6101             }
   6102             else
   6103             {
   6104                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   6105                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   6106             }
   6107         }
   6108     }
   6109 
   6110     switch(m_vc1_profile)
   6111     {
   6112         case VC1_AP:
   6113             DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
   6114             if (push_input_sc_codec(hComp) != OMX_ErrorNone)
   6115             {
   6116                 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
   6117                 return OMX_ErrorBadParameter;
   6118             }
   6119         break;
   6120 
   6121         case VC1_SP_MP_RCV:
   6122         default:
   6123             DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
   6124             return OMX_ErrorBadParameter;
   6125     }
   6126     return OMX_ErrorNone;
   6127 }
   6128 
   6129 bool omx_vdec::register_output_buffers()
   6130 {
   6131   struct vdec_ioctl_msg ioctl_msg;
   6132   struct vdec_setbuffer_cmd setbuffers;
   6133   int i = 0;
   6134   unsigned p1 =0,p2 = 0,ident = 0;
   6135 
   6136   for(i=0;i<m_out_buf_count;i++)
   6137   {
   6138     setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   6139     memcpy (&setbuffers.buffer,&driver_context.ptr_outputbuffer [i],
   6140             sizeof (vdec_bufferpayload));
   6141     ioctl_msg.inputparam  = &setbuffers;
   6142     ioctl_msg.outputparam = NULL;
   6143 
   6144     DEBUG_PRINT_LOW("\n Set the Output Buffer");
   6145     if (ioctl (driver_context.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
   6146          &ioctl_msg) < 0)
   6147     {
   6148       DEBUG_PRINT_ERROR("\n Set output buffer failed");
   6149       return false;
   6150     }
   6151   }
   6152   if(gate_output_buffers)
   6153   {
   6154     /*Generate FBD for all Buffers in the FTBq*/
   6155     pthread_mutex_lock(&m_lock);
   6156     DEBUG_PRINT_LOW("\n Initiate Pushing Output Buffers");
   6157     while (m_ftb_q.m_size)
   6158     {
   6159       m_ftb_q.pop_entry(&p1,&p2,&ident);
   6160       if(ident == OMX_COMPONENT_GENERATE_FTB )
   6161       {
   6162         if (fill_this_buffer_proxy ((OMX_HANDLETYPE)p1,
   6163                                     (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
   6164           {
   6165              DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
   6166              omx_report_error ();
   6167              return false;
   6168           }
   6169       }
   6170       else if (ident == OMX_COMPONENT_GENERATE_FBD)
   6171       {
   6172         fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   6173       }
   6174     }
   6175     gate_output_buffers = false;
   6176     pthread_mutex_unlock(&m_lock);
   6177   }
   6178   return true;
   6179 }
   6180 
   6181 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   6182                                   OMX_U32 alignment)
   6183 {
   6184 //TODO: figure out if this is really necessary (PMEM_ALLOCATE_ALIGNED is a
   6185 // QCOM extension to pmem
   6186   return true;
   6187 #if 0
   6188   struct pmem_allocation allocation;
   6189   allocation.size = buffer_size;
   6190   allocation.align = clip2(alignment);
   6191   if (allocation.align < 4096)
   6192   {
   6193     allocation.align = 4096;
   6194   }
   6195   if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
   6196   {
   6197     DEBUG_PRINT_ERROR("\n Aligment failed with pmem driver");
   6198     return false;
   6199   }
   6200   return true;
   6201 #endif
   6202 }
   6203 
   6204