Home | History | Annotate | Download | only in src
      1 /*---------------------------------------------------------------------------------------
      2 Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 
     29 /*============================================================================
     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_vdpp.cpp
     34   This module contains the implementation of the OpenMAX video post-processing component.
     35 
     36 *//*========================================================================*/
     37 
     38 //////////////////////////////////////////////////////////////////////////////
     39 //                             Include Files
     40 //////////////////////////////////////////////////////////////////////////////
     41 #define LOG_NDEBUG 0
     42 #include <string.h>
     43 #include <pthread.h>
     44 #include <sys/prctl.h>
     45 #include <stdlib.h>
     46 #include <unistd.h>
     47 #include <errno.h>
     48 #include "omx_vdpp.h"
     49 #include <fcntl.h>
     50 #include <limits.h>
     51 #include <media/msm_media_info.h>
     52 
     53 #ifndef _ANDROID_
     54 #include <sys/ioctl.h>
     55 #include <sys/mman.h>
     56 #endif //_ANDROID_
     57 
     58 #ifdef _ANDROID_
     59 #include <cutils/properties.h>
     60 #undef USE_EGL_IMAGE_GPU
     61 #endif
     62 
     63 #if  defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
     64 #include <gralloc_priv.h>
     65 #endif
     66 
     67 #ifdef INPUT_BUFFER_LOG
     68 int inputBufferFile;
     69 char inputfilename[] = "/sdcard/input-bitstream";
     70 #endif
     71 #ifdef OUTPUT_BUFFER_LOG
     72 int outputBufferFile;
     73 char outputfilename[] = "/sdcard/output.yuv";
     74 #endif
     75 #ifdef OUTPUT_EXTRADATA_LOG
     76 FILE *outputExtradataFile;
     77 char ouputextradatafilename[] = "/data/extradata";
     78 #endif
     79 
     80 #include <stdarg.h>
     81 #include <sys/stat.h>
     82 #include <dirent.h>
     83 
     84 #ifdef _ANDROID_
     85     extern "C"{
     86         #include<utils/Log.h>
     87     }
     88 #endif//_ANDROID_
     89 
     90 #define POLL_TIMEOUT 0x7fffffff //10000//
     91 #define MEM_DEVICE "/dev/ion"
     92 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
     93 
     94 #define DEFAULT_FPS 30
     95 #define MAX_INPUT_ERROR DEFAULT_FPS
     96 #define MAX_SUPPORTED_FPS 120
     97 
     98 #define SZ_4K 0x1000
     99 
    100 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    101 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    102 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
    103 
    104 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
    105 
    106 #ifndef STUB_VPU
    107 void* async_message_thread (void *input)
    108 {
    109   int extra_idx = 0;
    110   int rc = 0;
    111   OMX_BUFFERHEADERTYPE *buffer;
    112   struct v4l2_plane plane[VIDEO_MAX_PLANES];
    113   struct pollfd pfd[2];
    114   struct v4l2_buffer v4l2_buf;
    115   struct v4l2_event dqevent;
    116   omx_vdpp *omx = reinterpret_cast<omx_vdpp*>(input);
    117   pfd[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    118   pfd[0].fd = omx->drv_ctx.video_vpu_fd;
    119   pfd[1].events = POLLIN | POLLPRI | POLLERR;
    120   pfd[1].fd = omx->m_ctrl_in;
    121 
    122   memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    123   DEBUG_PRINT_LOW("omx_vdpp: Async thread start\n");
    124   prctl(PR_SET_NAME, (unsigned long)"VdppCallBackThread", 0, 0, 0);
    125   while (1)
    126   {
    127     rc = poll(pfd, 2, POLL_TIMEOUT);
    128 
    129     if (!rc) {
    130       DEBUG_PRINT_HIGH("Poll timedout\n");
    131       break; // no input buffers EOS reached
    132     } else if (rc < 0) {
    133       DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
    134       break;
    135     }
    136     //DEBUG_PRINT_LOW("async_message_thread 1 POLL_TIMEOUT = 0x%x", POLL_TIMEOUT);
    137 
    138     if (pfd[1].revents & (POLLIN | POLLPRI | POLLERR))
    139     {
    140       DEBUG_PRINT_HIGH("pipe event, exit async thread");
    141       break;
    142     }
    143 
    144     // output buffer ready for fbd
    145     if ((pfd[0].revents & POLLIN) || (pfd[0].revents & POLLRDNORM)) {
    146     //DEBUG_PRINT_LOW("async_message_thread 1\n");
    147     struct vdpp_msginfo vdpp_msg;
    148     v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    149     v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    150     v4l2_buf.length = omx->drv_ctx.output_num_planes;
    151     v4l2_buf.m.planes = plane;
    152     while(!ioctl(pfd[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    153         DEBUG_PRINT_LOW("async_message_thread 2\n");
    154         vdpp_msg.msgcode=VDPP_MSG_RESP_OUTPUT_BUFFER_DONE;
    155         vdpp_msg.status_code=VDPP_S_SUCCESS;
    156         vdpp_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    157 
    158         // driver returns ION buffer address, but case VDPP_MSG_RESP_OUTPUT_BUFFER_DONE
    159         // will pass mmaped address to upper layer, and then driver sets it when returnning
    160         // DQBUF for output buffers.
    161         extra_idx = EXTRADATA_IDX(omx->drv_ctx.output_num_planes);
    162         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
    163             // this len is used in fill_buffer_done buffer->nFilledLen
    164             // is different from FTBProxy plane[0].length
    165             vdpp_msg.msgdata.output_frame.len= v4l2_buf.m.planes[0].bytesused + v4l2_buf.m.planes[extra_idx].bytesused;
    166             //DEBUG_PRINT_HIGH("async_message_thread 2.5 omx->drv_ctx.op_buf.buffer_size = %d, plane[0].bytesused = %d, plane[%d].bytesused = %d\n", omx->drv_ctx.op_buf.buffer_size, v4l2_buf.m.planes[0].bytesused, extra_idx, v4l2_buf.m.planes[extra_idx].bytesused);
    167         }
    168         else {
    169             vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused;
    170             //DEBUG_PRINT_HIGH("async_message_thread 2.5 - 2 plane[0].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused);
    171         }
    172         vdpp_msg.msgdata.output_frame.bufferaddr=(void*)v4l2_buf.m.planes[0].m.userptr;
    173 
    174         // currently V4L2 driver just passes timestamp to maple FW, and maple FW
    175         // pass the timestamp back to OMX
    176         vdpp_msg.msgdata.output_frame.time_stamp = *(uint64_t *)(&v4l2_buf.timestamp);
    177 
    178         //DEBUG_PRINT_HIGH("async_message_thread 2.6.0 v4l2_buf.timestamp.tv_sec = 0x%08lx, v4l2_buf.timestamp.tv_usec = 0x%08lx\n", v4l2_buf.timestamp.tv_sec, v4l2_buf.timestamp.tv_usec);
    179         if (omx->async_message_process(input,&vdpp_msg) < 0) {
    180           DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    181           break;
    182         }
    183       }
    184     }
    185     // input buffer ready for empty buffer done (ebd)
    186       if((pfd[0].revents & POLLOUT) || (pfd[0].revents & POLLWRNORM)) {
    187       struct vdpp_msginfo vdpp_msg;
    188       v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    189       v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    190       v4l2_buf.length = omx->drv_ctx.input_num_planes;
    191       v4l2_buf.m.planes = plane;
    192       DEBUG_PRINT_LOW("async_message_thread 3\n");
    193       while(!ioctl(pfd[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    194         vdpp_msg.msgcode=VDPP_MSG_RESP_INPUT_BUFFER_DONE;
    195         vdpp_msg.status_code=VDPP_S_SUCCESS;
    196         vdpp_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    197 
    198         extra_idx = EXTRADATA_IDX(omx->drv_ctx.input_num_planes);
    199         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
    200             vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused + v4l2_buf.m.planes[extra_idx].bytesused; // user doesn't need this for ebd, just set in case is used
    201             //DEBUG_PRINT_HIGH("async_message_thread 3.5 plane[0].bytesused = %d, plane[extra_idx].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused, v4l2_buf.m.planes[extra_idx].bytesused);
    202         }
    203         else {
    204             vdpp_msg.msgdata.output_frame.len=v4l2_buf.m.planes[0].bytesused;
    205             //DEBUG_PRINT_HIGH("async_message_thread 3.5 - 2 plane[0].bytesused = %d\n", v4l2_buf.m.planes[0].bytesused);
    206         }
    207         if (omx->async_message_process(input,&vdpp_msg) < 0) {
    208           DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    209           break;
    210         }
    211       }
    212     }
    213     if (pfd[0].revents & POLLPRI){
    214       DEBUG_PRINT_HIGH("async_message_thread 4\n");
    215       memset(&dqevent, 0, sizeof(struct v4l2_event));
    216       rc = ioctl(pfd[0].fd, VIDIOC_DQEVENT, &dqevent);
    217       if(dqevent.type == VPU_EVENT_HW_ERROR)
    218       {
    219         struct vdpp_msginfo vdpp_msg;
    220         vdpp_msg.msgcode=VDPP_MSG_EVT_HW_ERROR;
    221         vdpp_msg.status_code=VDPP_S_SUCCESS;
    222         DEBUG_PRINT_HIGH(" SYS Error Recieved \n");
    223         if (omx->async_message_process(input,&vdpp_msg) < 0)
    224         {
    225           DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    226           break;
    227         }
    228       }
    229       else if (dqevent.type == VPU_EVENT_FLUSH_DONE) {
    230         struct vdpp_msginfo vdpp_msg;
    231         enum v4l2_buf_type buf_type;
    232         memcpy(&buf_type, dqevent.u.data, sizeof(buf_type));
    233         if(V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE == buf_type)
    234         {
    235             vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_INPUT_DONE;
    236             vdpp_msg.status_code=VDPP_S_SUCCESS;
    237             DEBUG_PRINT_HIGH("VDPP Input Flush Done Recieved \n");
    238             if (omx->async_message_process(input,&vdpp_msg) < 0) {
    239                 DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    240                 break;
    241             }
    242         }
    243         else if(V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE == buf_type)
    244         {
    245             vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_OUTPUT_DONE;
    246             vdpp_msg.status_code=VDPP_S_SUCCESS;
    247             DEBUG_PRINT_HIGH("VDPP Output Flush Done Recieved \n");
    248             if (omx->async_message_process(input,&vdpp_msg) < 0) {
    249                 DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    250                 break;
    251             }
    252         }
    253         else
    254         {
    255             DEBUG_PRINT_HIGH(" Wrong buf_type recieved %d\n", buf_type);
    256         }
    257       }
    258       else if(dqevent.type == VPU_EVENT_ACTIVE_REGION_CHANGED)
    259       {
    260         DEBUG_PRINT_HIGH(" VPU_EVENT_ACTIVE_REGION_CHANGED\n");
    261         struct vdpp_msginfo vdpp_msg;
    262         vdpp_msg.msgcode=VDPP_MSG_EVT_ACTIVE_REGION_DETECTION_STATUS;
    263         vdpp_msg.status_code=VDPP_S_SUCCESS;
    264 
    265         // get the active region dection result struct from the event associated data
    266         memcpy(&vdpp_msg.msgdata.ar_result, dqevent.u.data, sizeof(v4l2_rect));
    267         DEBUG_PRINT_HIGH(" VPU_EVENT_ACTIVE_REGION_CHANGED Recieved \n");
    268         if(omx->m_ar_callback_setup)
    269         {
    270             if (omx->async_message_process(input,&vdpp_msg) < 0)
    271             {
    272               DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    273               break;
    274             }
    275         }
    276       }
    277       else
    278       {
    279         DEBUG_PRINT_HIGH(" VPU Some Event recieved \n");
    280         continue;
    281       }
    282 
    283     }
    284   }
    285   DEBUG_PRINT_HIGH("omx_vdpp: Async thread stop\n");
    286   return NULL;
    287 }
    288 #else // use stub to simulate vpu events for now
    289 void* async_message_thread (void *input)
    290 {
    291   OMX_BUFFERHEADERTYPE *buffer;
    292   struct v4l2_plane plane[VIDEO_MAX_PLANES];
    293   struct pollfd pfd;
    294   struct v4l2_buffer v4l2_buf;
    295   memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    296   struct v4l2_event dqevent;
    297   omx_vdpp *omx = reinterpret_cast<omx_vdpp*>(input);
    298 
    299   pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    300   pfd.fd = omx->drv_ctx.video_vpu_fd;
    301   int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    302   DEBUG_PRINT_HIGH("omx_vdpp: Async thread start\n");
    303   prctl(PR_SET_NAME, (unsigned long)"VdppCallBackThread", 0, 0, 0);
    304   while (1)
    305   {
    306     DEBUG_PRINT_HIGH("omx_vdpp: Async thread start 0\n");
    307     sem_wait(&(omx->drv_ctx.async_lock));
    308     DEBUG_PRINT_HIGH("omx_vdpp: Async thread start pfd.revents = %d\n", pfd.revents);
    309     if ((omx->drv_ctx.etb_ftb_info.ftb_cnt > 0))
    310     {
    311       DEBUG_PRINT_LOW("async_message_thread 1 omx->drv_ctx.etb_ftb_info.ftb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.ftb_cnt);
    312       struct vdpp_msginfo vdpp_msg;
    313       unsigned p1 = 0;
    314       unsigned p2 = 0;
    315       unsigned ident = 0;
    316       v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    317       v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    318       omx->m_index_q_ftb.pop_entry(&p1,&p2,&ident);
    319       v4l2_buf.index = ident;
    320       v4l2_buf.bytesused = omx->drv_ctx.etb_ftb_info.ftb_len;
    321       omx->drv_ctx.etb_ftb_info.ftb_cnt--;
    322       DEBUG_PRINT_HIGH("async_message_thread 1.5 omx->drv_ctx.etb_ftb_info.ftb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.ftb_cnt);
    323       /*while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) */{
    324       DEBUG_PRINT_LOW("async_message_thread 2\n", rc);
    325         vdpp_msg.msgcode=VDPP_MSG_RESP_OUTPUT_BUFFER_DONE;
    326         vdpp_msg.status_code=VDPP_S_SUCCESS;
    327         vdpp_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    328         vdpp_msg.msgdata.output_frame.len=v4l2_buf.bytesused;
    329         vdpp_msg.msgdata.output_frame.bufferaddr=(void*)v4l2_buf.m.userptr;
    330 
    331         vdpp_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    332           (uint64_t)v4l2_buf.timestamp.tv_usec;
    333         if (omx->async_message_process(input,&vdpp_msg) < 0) {
    334           DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    335           break;
    336         }
    337       }
    338     }
    339     if(omx->drv_ctx.etb_ftb_info.etb_cnt > 0) {
    340       struct vdpp_msginfo vdpp_msg;
    341       unsigned p1 = 0;
    342       unsigned p2 = 0;
    343       unsigned ident = 0;
    344       v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    345       v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    346 
    347       omx->m_index_q_etb.pop_entry(&p1,&p2,&ident);
    348       v4l2_buf.index = ident;
    349       DEBUG_PRINT_LOW("async_message_thread 3 omx->drv_ctx.etb_ftb_info.etb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.etb_cnt);
    350       omx->drv_ctx.etb_ftb_info.etb_cnt--;
    351       DEBUG_PRINT_LOW("async_message_thread 4 omx->drv_ctx.etb_ftb_info.etb_cnt = %d\n", omx->drv_ctx.etb_ftb_info.etb_cnt);
    352 
    353       /*while(!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf))*/ {
    354         vdpp_msg.msgcode=VDPP_MSG_RESP_INPUT_BUFFER_DONE;
    355         vdpp_msg.status_code=VDPP_S_SUCCESS;
    356         vdpp_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    357         if (omx->async_message_process(input,&vdpp_msg) < 0) {
    358           DEBUG_PRINT_HIGH(" async_message_thread Exited  \n");
    359           break;
    360         }
    361       }
    362     }
    363 
    364     if(omx->drv_ctx.thread_exit)
    365     {
    366         break;
    367     }
    368   }
    369   DEBUG_PRINT_HIGH("omx_vdpp: Async thread stop\n");
    370   return NULL;
    371 }
    372 #endif
    373 
    374 void* message_thread(void *input)
    375 {
    376   omx_vdpp* omx = reinterpret_cast<omx_vdpp*>(input);
    377   unsigned char id;
    378   int n;
    379 
    380   DEBUG_PRINT_LOW("omx_vdpp: message thread start\n");
    381   prctl(PR_SET_NAME, (unsigned long)"VideoPostProcessingMsgThread", 0, 0, 0);
    382   while (1)
    383   {
    384 
    385     n = read(omx->m_pipe_in, &id, 1);
    386 
    387     if(0 == n)
    388     {
    389       break;
    390     }
    391 
    392     if (1 == n)
    393     {
    394         omx->process_event_cb(omx, id);
    395     }
    396     if ((n < 0) && (errno != EINTR))
    397     {
    398       DEBUG_PRINT_ERROR("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    399       break;
    400     }
    401   }
    402   DEBUG_PRINT_HIGH("omx_vdpp: message thread stop\n");
    403   return 0;
    404 }
    405 
    406 void post_message(omx_vdpp *omx, unsigned char id)
    407 {
    408       int ret_value;
    409       //DEBUG_PRINT_LOW("omx_vdpp: post_message %d pipe out 0x%x\n", id,omx->m_pipe_out);
    410       ret_value = write(omx->m_pipe_out, &id, 1);
    411       //DEBUG_PRINT_HIGH("post_message to pipe done %d\n",ret_value);
    412 }
    413 
    414 // omx_cmd_queue destructor
    415 omx_vdpp::omx_cmd_queue::~omx_cmd_queue()
    416 {
    417   // Nothing to do
    418 }
    419 
    420 // omx cmd queue constructor
    421 omx_vdpp::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    422 {
    423     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    424 }
    425 
    426 // omx cmd queue insert
    427 bool omx_vdpp::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
    428 {
    429   bool ret = true;
    430   if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
    431   {
    432     m_q[m_write].id       = id;
    433     m_q[m_write].param1   = p1;
    434     m_q[m_write].param2   = p2;
    435     m_write++;
    436     m_size ++;
    437     if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
    438     {
    439       m_write = 0;
    440     }
    441   }
    442   else
    443   {
    444     ret = false;
    445     DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
    446   }
    447   return ret;
    448 }
    449 
    450 // omx cmd queue pop
    451 bool omx_vdpp::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
    452 {
    453   bool ret = true;
    454   if (m_size > 0)
    455   {
    456     *id = m_q[m_read].id;
    457     *p1 = m_q[m_read].param1;
    458     *p2 = m_q[m_read].param2;
    459     // Move the read pointer ahead
    460     ++m_read;
    461     --m_size;
    462     if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
    463     {
    464       m_read = 0;
    465     }
    466   }
    467   else
    468   {
    469     ret = false;
    470   }
    471   return ret;
    472 }
    473 
    474 // Retrieve the first mesg type in the queue
    475 unsigned omx_vdpp::omx_cmd_queue::get_q_msg_type()
    476 {
    477     return m_q[m_read].id;
    478 }
    479 
    480 #ifdef _ANDROID_
    481 omx_vdpp::ts_arr_list::ts_arr_list()
    482 {
    483   //initialize timestamps array
    484   memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    485 }
    486 omx_vdpp::ts_arr_list::~ts_arr_list()
    487 {
    488   //free m_ts_arr_list?
    489 }
    490 
    491 bool omx_vdpp::ts_arr_list::insert_ts(OMX_TICKS ts)
    492 {
    493   bool ret = true;
    494   bool duplicate_ts = false;
    495   int idx = 0;
    496 
    497   //insert at the first available empty location
    498   for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
    499   {
    500     if (!m_ts_arr_list[idx].valid)
    501     {
    502       //found invalid or empty entry, save timestamp
    503       m_ts_arr_list[idx].valid = true;
    504       m_ts_arr_list[idx].timestamp = ts;
    505       DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    506                        ts, idx);
    507       break;
    508     }
    509   }
    510 
    511   if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS)
    512   {
    513     DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    514     ret = false;
    515   }
    516   return ret;
    517 }
    518 
    519 bool omx_vdpp::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    520 {
    521   bool ret = true;
    522   int min_idx = -1;
    523   OMX_TICKS min_ts = 0;
    524   int idx = 0;
    525 
    526   for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
    527   {
    528 
    529     if (m_ts_arr_list[idx].valid)
    530     {
    531       //found valid entry, save index
    532       if (min_idx < 0)
    533       {
    534         //first valid entry
    535         min_ts = m_ts_arr_list[idx].timestamp;
    536         min_idx = idx;
    537       }
    538       else if (m_ts_arr_list[idx].timestamp < min_ts)
    539       {
    540         min_ts = m_ts_arr_list[idx].timestamp;
    541         min_idx = idx;
    542       }
    543     }
    544 
    545   }
    546 
    547   if (min_idx < 0)
    548   {
    549     //no valid entries found
    550     DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    551     ts = 0;
    552     ret = false;
    553   }
    554   else
    555   {
    556     ts = m_ts_arr_list[min_idx].timestamp;
    557     m_ts_arr_list[min_idx].valid = false;
    558     DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    559                      ts, min_idx);
    560   }
    561 
    562   return ret;
    563 
    564 }
    565 
    566 
    567 bool omx_vdpp::ts_arr_list::reset_ts_list()
    568 {
    569   bool ret = true;
    570   int idx = 0;
    571 
    572   DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    573   for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++)
    574   {
    575     m_ts_arr_list[idx].valid = false;
    576   }
    577   return ret;
    578 }
    579 #endif
    580 
    581 // factory function executed by the core to create instances
    582 void *get_omx_component_factory_fn(void)
    583 {
    584   return (new omx_vdpp);
    585 }
    586 
    587 /* ======================================================================
    588 FUNCTION
    589   omx_vdpp::omx_vdpp
    590 
    591 DESCRIPTION
    592   Constructor
    593 
    594 PARAMETERS
    595   None
    596 
    597 RETURN VALUE
    598   None.
    599 ========================================================================== */
    600 omx_vdpp::omx_vdpp(): m_ar_callback_setup(false),
    601     m_error_propogated(false),
    602 	m_state(OMX_StateInvalid),
    603 	m_app_data(NULL),
    604 	m_inp_mem_ptr(NULL),
    605 	m_out_mem_ptr(NULL),
    606 	m_inp_err_count(0),
    607 	input_flush_progress (false),
    608 	output_flush_progress (false),
    609 	input_use_buffer (false),
    610 	output_use_buffer (false),
    611 	ouput_egl_buffers(false),
    612 	m_use_output_pmem(OMX_FALSE),
    613 	m_out_mem_region_smi(OMX_FALSE),
    614 	m_out_pvt_entry_pmem(OMX_FALSE),
    615 	pending_input_buffers(0),
    616 	pending_output_buffers(0),
    617     input_qbuf_count(0),
    618     input_dqbuf_count(0),
    619     output_qbuf_count(0),
    620     output_dqbuf_count(0),
    621 #ifdef OUTPUT_BUFFER_LOG
    622     output_buffer_write_counter(0),
    623     input_buffer_write_counter(0),
    624 #endif
    625 	m_out_bm_count(0),
    626 	m_inp_bm_count(0),
    627 	m_inp_bPopulated(OMX_FALSE),
    628 	m_out_bPopulated(OMX_FALSE),
    629 	m_flags(0),
    630 	m_inp_bEnabled(OMX_TRUE),
    631 	m_out_bEnabled(OMX_TRUE),
    632 	m_in_alloc_cnt(0),
    633 	m_platform_list(NULL),
    634 	m_platform_entry(NULL),
    635 	m_pmem_info(NULL),
    636 	psource_frame (NULL),
    637 	pdest_frame (NULL),
    638 	m_inp_heap_ptr (NULL),
    639 	m_phdr_pmem_ptr(NULL),
    640 	m_heap_inp_bm_count (0),
    641 	prev_ts(LLONG_MAX),
    642 	rst_prev_ts(true),
    643 	frm_int(0),
    644 	in_reconfig(false),
    645     client_extradata(0),
    646 	m_enable_android_native_buffers(OMX_FALSE),
    647 	m_use_android_native_buffers(OMX_FALSE),
    648     client_set_fps(false),
    649     interlace_user_flag(false)
    650 {
    651   DEBUG_PRINT_LOW("In OMX vdpp Constructor");
    652 
    653   memset(&m_cmp,0,sizeof(m_cmp));
    654   memset(&m_cb,0,sizeof(m_cb));
    655   memset (&drv_ctx,0,sizeof(drv_ctx));
    656   msg_thread_id = 0;
    657   async_thread_id = 0;
    658   msg_thread_created = false;
    659   async_thread_created = false;
    660 #ifdef _ANDROID_ICS_
    661   memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    662 #endif
    663 
    664   drv_ctx.timestamp_adjust = false;
    665   drv_ctx.video_vpu_fd = -1;
    666   pthread_mutex_init(&m_lock, NULL);
    667   sem_init(&m_cmd_lock,0,0);
    668   streaming[CAPTURE_PORT] = false;
    669   streaming[OUTPUT_PORT] = false;
    670 
    671   m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    672 
    673 #ifdef STUB_VPU
    674   drv_ctx.thread_exit = false;
    675   sem_init(&(drv_ctx.async_lock),0,0);
    676 #endif
    677 }
    678 
    679 static OMX_ERRORTYPE subscribe_to_events(int fd)
    680 {
    681 	OMX_ERRORTYPE eRet = OMX_ErrorNone;
    682 	struct v4l2_event_subscription sub;
    683 	int rc;
    684 	if (fd < 0) {
    685 		DEBUG_PRINT_ERROR("Invalid input: %d\n", fd);
    686 		return OMX_ErrorBadParameter;
    687 	}
    688 
    689 #ifndef STUB_VPU
    690       sub.type = V4L2_EVENT_ALL;
    691 	  rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    692 	  if (rc < 0)
    693       {
    694 		DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x\n", sub.type);
    695 		eRet = OMX_ErrorNotImplemented;
    696 	  }
    697 #endif
    698 
    699 	return eRet;
    700 }
    701 
    702 
    703 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    704 {
    705 	OMX_ERRORTYPE eRet = OMX_ErrorNone;
    706 	struct v4l2_event_subscription sub;
    707 
    708 	int rc;
    709 	if (fd < 0) {
    710 		DEBUG_PRINT_ERROR("Invalid input: %d\n", fd);
    711 		return OMX_ErrorBadParameter;
    712 	}
    713 
    714 #ifndef STUB_VPU
    715 	memset(&sub, 0, sizeof(sub));
    716 	sub.type = V4L2_EVENT_ALL;
    717 	rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    718 	if (rc) {
    719 		DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x\n", sub.type);
    720 	}
    721 #endif
    722 
    723 	return eRet;
    724 }
    725 
    726 /* ======================================================================
    727 FUNCTION
    728   omx_vdpp::~omx_vdpp
    729 
    730 DESCRIPTION
    731   Destructor
    732 
    733 PARAMETERS
    734   None
    735 
    736 RETURN VALUE
    737   None.
    738 ========================================================================== */
    739 omx_vdpp::~omx_vdpp()
    740 {
    741   m_pmem_info = NULL;
    742   DEBUG_PRINT_HIGH("In OMX vdpp Destructor");
    743   if(m_pipe_in) close(m_pipe_in);
    744   if(m_pipe_out) close(m_pipe_out);
    745   m_pipe_in = -1;
    746   m_pipe_out = -1;
    747   DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    748   if (msg_thread_created)
    749     pthread_join(msg_thread_id,NULL);
    750   DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    751 
    752 #ifdef STUB_VPU
    753   DEBUG_PRINT_HIGH("drv_ctx.etb_ftb_info.ftb_cnt = %d, drv_ctx.etb_ftb_info.etb_cnt = %d", drv_ctx.etb_ftb_info.ftb_cnt, drv_ctx.etb_ftb_info.etb_cnt);
    754   drv_ctx.etb_ftb_info.ftb_cnt = 0;
    755   drv_ctx.etb_ftb_info.etb_cnt = 0;
    756   sem_post (&(drv_ctx.async_lock));
    757   drv_ctx.thread_exit = true;
    758 #endif
    759   // notify async thread to exit
    760   DEBUG_PRINT_LOW("write control pipe to notify async thread to exit");
    761   write(m_ctrl_out, "1", 1);
    762 
    763   if (async_thread_created)
    764     pthread_join(async_thread_id,NULL);
    765   DEBUG_PRINT_HIGH("async_thread exits");
    766   unsubscribe_to_events(drv_ctx.video_vpu_fd);
    767   close(drv_ctx.video_vpu_fd);
    768   pthread_mutex_destroy(&m_lock);
    769   sem_destroy(&m_cmd_lock);
    770 
    771 #ifdef STUB_VPU
    772   sem_destroy(&(drv_ctx.async_lock));
    773 #endif
    774   if(m_ctrl_in) close(m_ctrl_in);
    775   if(m_ctrl_out) close(m_ctrl_out);
    776   m_ctrl_in = -1;
    777   m_ctrl_out = -1;
    778   DEBUG_PRINT_HIGH("Exit OMX vdpp Destructor");
    779 }
    780 
    781 int release_buffers(omx_vdpp* obj, enum vdpp_buffer buffer_type) {
    782 	struct v4l2_requestbuffers bufreq;
    783 	int rc = 0;
    784 #ifndef STUB_VPU
    785 	if (buffer_type == VDPP_BUFFER_TYPE_OUTPUT){
    786 		bufreq.memory = V4L2_MEMORY_USERPTR;
    787 		bufreq.count = 0;
    788 		bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    789 		rc = ioctl(obj->drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
    790 	}else if(buffer_type == VDPP_BUFFER_TYPE_INPUT) {
    791         bufreq.memory = V4L2_MEMORY_USERPTR;
    792         bufreq.count = 0;
    793         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    794         rc = ioctl(obj->drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
    795     }
    796 #endif
    797 	return rc;
    798 }
    799 
    800 /* ======================================================================
    801 FUNCTION
    802   omx_vdpp::process_event_cb
    803 
    804 DESCRIPTION
    805   IL Client callbacks are generated through this routine. The VDPP
    806   provides the thread context for this routine.
    807 
    808 PARAMETERS
    809   ctxt -- Context information related to the self.
    810   id   -- Event identifier. This could be any of the following:
    811           1. Command completion event
    812           2. Buffer done callback event
    813           3. Frame done callback event
    814 
    815 RETURN VALUE
    816   None.
    817 
    818 ========================================================================== */
    819 void omx_vdpp::process_event_cb(void *ctxt, unsigned char id)
    820 {
    821   signed p1; // Parameter - 1
    822   signed p2; // Parameter - 2
    823   unsigned ident;
    824   unsigned qsize=0; // qsize
    825   omx_vdpp *pThis = (omx_vdpp *) ctxt;
    826 
    827   if(!pThis)
    828   {
    829     DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
    830         __func__);
    831     return;
    832   }
    833 
    834   // Protect the shared queue data structure
    835   do
    836   {
    837     /*Read the message id's from the queue*/
    838     pthread_mutex_lock(&pThis->m_lock);
    839 
    840     // first check command queue
    841     qsize = pThis->m_cmd_q.m_size;
    842     if(qsize)
    843     {
    844       pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    845       //DEBUG_PRINT_HIGH("process_event_cb m_cmd_q.pop_entry ident = %d", ident);
    846     }
    847 
    848     // then check ftb queue
    849     if (qsize == 0 && pThis->m_state != OMX_StatePause)
    850     {
    851 
    852       qsize = pThis->m_ftb_q.m_size;
    853       if (qsize)
    854       {
    855         pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    856         DEBUG_PRINT_HIGH("process_event_cb, p1 = 0x%08x, p2 = 0x%08x, ident = 0x%08x", p1, p2, ident);
    857       }
    858     }
    859 
    860     // last check etb queue
    861     if (qsize == 0 && pThis->m_state != OMX_StatePause)
    862     {
    863       qsize = pThis->m_etb_q.m_size;
    864       if (qsize)
    865       {
    866         pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    867       }
    868     }
    869     pthread_mutex_unlock(&pThis->m_lock);
    870 
    871     /*process message if we have one*/
    872     if(qsize > 0)
    873     {
    874       id = ident;
    875       switch (id)
    876       {
    877         case OMX_COMPONENT_GENERATE_EVENT:
    878           if (pThis->m_cb.EventHandler)
    879           {
    880             switch (p1)
    881             {
    882               case OMX_CommandStateSet:
    883                 pThis->m_state = (OMX_STATETYPE) p2;
    884                 DEBUG_PRINT_HIGH(" OMX_CommandStateSet complete, m_state = %d, pThis->m_cb.EventHandler = %p",
    885                     pThis->m_state, pThis->m_cb.EventHandler);
    886                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    887                                       OMX_EventCmdComplete, p1, p2, NULL);
    888                 break;
    889 
    890               case OMX_EventError:
    891                 if(p2 == OMX_StateInvalid)
    892                 {
    893                     DEBUG_PRINT_ERROR(" OMX_EventError: p2 is OMX_StateInvalid");
    894                     pThis->m_state = (OMX_STATETYPE) p2;
    895                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    896                                OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    897                 }
    898                 else if (p2 == OMX_ErrorHardware)
    899                 {
    900                    pThis->omx_report_error();
    901                 }
    902                 else
    903 		        {
    904                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    905                                       OMX_EventError, p2, (OMX_U32)NULL, NULL );
    906                 }
    907                 break;
    908 
    909               case OMX_CommandPortDisable:
    910                 DEBUG_PRINT_HIGH(" OMX_CommandPortDisable complete for port [%d], pThis->in_reconfig = %d", p2, pThis->in_reconfig);
    911                 if (BITMASK_PRESENT(&pThis->m_flags,
    912                     OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
    913                 {
    914                   BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
    915                   break;
    916                 }
    917                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX)
    918                 {
    919 				  OMX_ERRORTYPE eRet = OMX_ErrorNone;
    920 				  pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
    921 				  if(release_buffers(pThis, VDPP_BUFFER_TYPE_OUTPUT))
    922 					  DEBUG_PRINT_HIGH("Failed to release output buffers\n");
    923 				  OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
    924 				  pThis->in_reconfig = false;
    925                   if(eRet !=  OMX_ErrorNone)
    926                   {
    927                       DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
    928                       pThis->omx_report_error();
    929                       break;
    930                   }
    931                 }
    932                 if (p2 == OMX_CORE_INPUT_PORT_INDEX)
    933                 {
    934 				  OMX_ERRORTYPE eRet = OMX_ErrorNone;
    935 				  pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX);
    936 				  if(release_buffers(pThis, VDPP_BUFFER_TYPE_INPUT))
    937 					  DEBUG_PRINT_HIGH("Failed to release output buffers\n");
    938 				  OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.ip_buf);
    939 				  pThis->in_reconfig = false;
    940                   if(eRet !=  OMX_ErrorNone)
    941                   {
    942                       DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
    943                       pThis->omx_report_error();
    944                       break;
    945                   }
    946                 }
    947                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    948                                       OMX_EventCmdComplete, p1, p2, NULL );
    949                 break;
    950               case OMX_CommandPortEnable:
    951                 DEBUG_PRINT_HIGH(" OMX_CommandPortEnable complete for port [%d]", p2);
    952                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    953                                       OMX_EventCmdComplete, p1, p2, NULL );
    954                 break;
    955 
    956               default:
    957                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    958                                          OMX_EventCmdComplete, p1, p2, NULL );
    959                 break;
    960 
    961             }
    962           }
    963           else
    964           {
    965             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
    966           }
    967           break;
    968       break;
    969         case OMX_COMPONENT_GENERATE_ETB:
    970           if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    971               (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    972           {
    973             DEBUG_PRINT_ERROR(" empty_this_buffer_proxy failure");
    974             pThis->omx_report_error ();
    975           }
    976          break;
    977 
    978         case OMX_COMPONENT_GENERATE_FTB:
    979             {
    980               DEBUG_PRINT_HIGH("OMX_COMPONENT_GENERATE_FTB p2 = 0x%08x", p2);
    981               if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    982                    (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
    983               {
    984                  DEBUG_PRINT_ERROR(" fill_this_buffer_proxy failure");
    985                  pThis->omx_report_error ();
    986               }
    987             }
    988         break;
    989 
    990         case OMX_COMPONENT_GENERATE_COMMAND:
    991           pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    992                                     (OMX_U32)p2,(OMX_PTR)NULL);
    993           break;
    994 
    995         case OMX_COMPONENT_GENERATE_EBD:
    996           if (p2 != VDPP_S_SUCCESS && p2 != VDPP_S_INPUT_BITSTREAM_ERR)
    997           {
    998             DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD failure");
    999             pThis->omx_report_error ();
   1000           }
   1001           else
   1002           {
   1003             DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD 1");
   1004             if (p2 == VDPP_S_INPUT_BITSTREAM_ERR && p1)
   1005             {
   1006               pThis->m_inp_err_count++;
   1007               DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_EBD 2");
   1008               //pThis->time_stamp_dts.remove_time_stamp(
   1009               //((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
   1010               //(pThis->drv_ctx.interlace != VDPP_InterlaceFrameProgressive)
   1011               //  ?true:false);
   1012             }
   1013             else
   1014             {
   1015               pThis->m_inp_err_count = 0;
   1016             }
   1017             if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1018                  (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
   1019             {
   1020                DEBUG_PRINT_ERROR(" empty_buffer_done failure");
   1021                pThis->omx_report_error ();
   1022             }
   1023             DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EBD 4");
   1024             if(pThis->m_inp_err_count >= MAX_INPUT_ERROR)
   1025             {
   1026                DEBUG_PRINT_ERROR(" Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
   1027                pThis->omx_report_error ();
   1028             }
   1029           }
   1030           break;
   1031         case OMX_COMPONENT_GENERATE_FBD:
   1032           if (p2 != VDPP_S_SUCCESS)
   1033           {
   1034             DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_FBD failure");
   1035             pThis->omx_report_error ();
   1036           }
   1037           else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1038                   (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
   1039           {
   1040             DEBUG_PRINT_ERROR(" fill_buffer_done failure");
   1041             pThis->omx_report_error ();
   1042           }
   1043           break;
   1044 
   1045         case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1046           DEBUG_PRINT_HIGH(" Driver flush i/p Port complete");
   1047           if (!pThis->input_flush_progress)
   1048           {
   1049             DEBUG_PRINT_ERROR(" WARNING: Unexpected flush from driver");
   1050           }
   1051           else
   1052           {
   1053             pThis->execute_input_flush();
   1054             if (pThis->m_cb.EventHandler)
   1055             {
   1056               if (p2 != VDPP_S_SUCCESS)
   1057               {
   1058                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1059                 pThis->omx_report_error ();
   1060               }
   1061               else
   1062               {
   1063                 /*Check if we need generate event for Flush done*/
   1064                 if(BITMASK_PRESENT(&pThis->m_flags,
   1065                                    OMX_COMPONENT_INPUT_FLUSH_PENDING))
   1066                 {
   1067                   BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1068                   DEBUG_PRINT_LOW(" Input Flush completed - Notify Client");
   1069                   pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1070                                            OMX_EventCmdComplete,OMX_CommandFlush,
   1071                                            OMX_CORE_INPUT_PORT_INDEX,NULL );
   1072                 }
   1073                 if (BITMASK_PRESENT(&pThis->m_flags,
   1074                                          OMX_COMPONENT_IDLE_PENDING))
   1075                 {
   1076                    if(pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1077                            DEBUG_PRINT_ERROR(" Failed to call streamoff on OUTPUT Port \n");
   1078 						   pThis->omx_report_error ();
   1079 				   } else {
   1080                        DEBUG_PRINT_HIGH(" Successful to call streamoff on OUTPUT Port \n");
   1081 					   pThis->streaming[OUTPUT_PORT] = false;
   1082 				   }
   1083                   if (!pThis->output_flush_progress)
   1084                   {
   1085                      DEBUG_PRINT_LOW(" Input flush done hence issue stop");
   1086 					 pThis->post_event ((unsigned int)NULL, VDPP_S_SUCCESS,\
   1087 							 OMX_COMPONENT_GENERATE_STOP_DONE);
   1088                   }
   1089                 }
   1090               }
   1091             }
   1092             else
   1093             {
   1094               DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1095             }
   1096           }
   1097           break;
   1098 
   1099         case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1100           DEBUG_PRINT_HIGH(" Driver flush o/p Port complete");
   1101           if (!pThis->output_flush_progress)
   1102           {
   1103             DEBUG_PRINT_ERROR(" WARNING: Unexpected flush from driver");
   1104           }
   1105           else
   1106           {
   1107             pThis->execute_output_flush();
   1108             if (pThis->m_cb.EventHandler)
   1109             {
   1110               if (p2 != VDPP_S_SUCCESS)
   1111               {
   1112                 DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1113                 pThis->omx_report_error ();
   1114               }
   1115               else
   1116               {
   1117                 /*Check if we need generate event for Flush done*/
   1118                 if(BITMASK_PRESENT(&pThis->m_flags,
   1119                                    OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
   1120                 {
   1121                   DEBUG_PRINT_LOW(" Notify Output Flush done");
   1122                   BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1123                   pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1124                                            OMX_EventCmdComplete,OMX_CommandFlush,
   1125                                            OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   1126                 }
   1127                 if(BITMASK_PRESENT(&pThis->m_flags,
   1128                        OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING))
   1129                 {
   1130                   DEBUG_PRINT_LOW(" Internal flush complete");
   1131                   BITMASK_CLEAR (&pThis->m_flags,
   1132                                  OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1133                   if (BITMASK_PRESENT(&pThis->m_flags,
   1134                           OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED))
   1135                   {
   1136                     pThis->post_event(OMX_CommandPortDisable,
   1137                                OMX_CORE_OUTPUT_PORT_INDEX,
   1138                                OMX_COMPONENT_GENERATE_EVENT);
   1139                     BITMASK_CLEAR (&pThis->m_flags,
   1140                                    OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1141 
   1142                   }
   1143                 }
   1144 
   1145                 DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH 1  \n");
   1146 
   1147                 if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
   1148                 {
   1149                    DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH  2 \n");
   1150                    if(pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1151                            DEBUG_PRINT_ERROR(" Failed to call streamoff on CAPTURE Port \n");
   1152 						   pThis->omx_report_error ();
   1153 						   break;
   1154                    }
   1155 				   pThis->streaming[CAPTURE_PORT] = false;
   1156                    DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH  3 pThis->input_flush_progress =%d \n", pThis->input_flush_progress);
   1157                   if (!pThis->input_flush_progress)
   1158                   {
   1159                     DEBUG_PRINT_LOW(" Output flush done hence issue stop");
   1160 					 pThis->post_event ((unsigned int)NULL, VDPP_S_SUCCESS,\
   1161 							 OMX_COMPONENT_GENERATE_STOP_DONE);
   1162                   }
   1163                 }
   1164               }
   1165             }
   1166             else
   1167             {
   1168               DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1169             }
   1170           }
   1171           break;
   1172 
   1173         case OMX_COMPONENT_GENERATE_START_DONE:
   1174           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1175 
   1176           if (pThis->m_cb.EventHandler)
   1177           {
   1178             if (p2 != VDPP_S_SUCCESS)
   1179             {
   1180               DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_START_DONE Failure");
   1181               pThis->omx_report_error ();
   1182             }
   1183             else
   1184             {
   1185               DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_START_DONE Success");
   1186               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
   1187               {
   1188                 DEBUG_PRINT_LOW(" Move to executing");
   1189                 // Send the callback now
   1190                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1191                 pThis->m_state = OMX_StateExecuting;
   1192                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1193                                        OMX_EventCmdComplete,OMX_CommandStateSet,
   1194                                        OMX_StateExecuting, NULL);
   1195               }
   1196               else if (BITMASK_PRESENT(&pThis->m_flags,
   1197                                        OMX_COMPONENT_PAUSE_PENDING))
   1198               {
   1199                 if (/*ioctl (pThis->drv_ctx.video_vpu_fd,
   1200                            VDPP_IOCTL_CMD_PAUSE,NULL ) < */0)
   1201                 {
   1202                   DEBUG_PRINT_ERROR(" VDPP_IOCTL_CMD_PAUSE failed");
   1203                   pThis->omx_report_error ();
   1204                 }
   1205               }
   1206             }
   1207           }
   1208           else
   1209           {
   1210             DEBUG_PRINT_LOW(" Event Handler callback is NULL");
   1211           }
   1212           break;
   1213 
   1214         case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1215           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1216           if (pThis->m_cb.EventHandler)
   1217           {
   1218             if (p2 != VDPP_S_SUCCESS)
   1219             {
   1220               DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1221               pThis->omx_report_error ();
   1222             }
   1223             else
   1224             {
   1225               pThis->complete_pending_buffer_done_cbs();
   1226               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
   1227               {
   1228                 DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1229                 //Send the callback now
   1230                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1231                 pThis->m_state = OMX_StatePause;
   1232                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1233                                        OMX_EventCmdComplete,OMX_CommandStateSet,
   1234                                        OMX_StatePause, NULL);
   1235               }
   1236             }
   1237           }
   1238           else
   1239           {
   1240             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1241           }
   1242 
   1243           break;
   1244 
   1245         case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1246           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1247           if (pThis->m_cb.EventHandler)
   1248           {
   1249             if (p2 != VDPP_S_SUCCESS)
   1250             {
   1251               DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1252               pThis->omx_report_error ();
   1253             }
   1254             else
   1255             {
   1256               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
   1257               {
   1258                 DEBUG_PRINT_LOW(" Moving the VDPP to execute state");
   1259                 // Send the callback now
   1260                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1261                 pThis->m_state = OMX_StateExecuting;
   1262                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1263                                        OMX_EventCmdComplete,OMX_CommandStateSet,
   1264                                        OMX_StateExecuting,NULL);
   1265               }
   1266             }
   1267           }
   1268           else
   1269           {
   1270             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1271           }
   1272 
   1273           break;
   1274 
   1275         case OMX_COMPONENT_GENERATE_STOP_DONE:
   1276           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1277           if (pThis->m_cb.EventHandler)
   1278           {
   1279             if (p2 != VDPP_S_SUCCESS)
   1280             {
   1281               DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1282               pThis->omx_report_error ();
   1283             }
   1284             else
   1285             {
   1286               pThis->complete_pending_buffer_done_cbs();
   1287               if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
   1288               {
   1289                 DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1290                 // Send the callback now
   1291                 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1292                 pThis->m_state = OMX_StateIdle;
   1293                 DEBUG_PRINT_LOW(" Move to Idle State, pThis->m_cb.EventHandler = %p", pThis->m_cb.EventHandler);
   1294                 pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1295                                          OMX_EventCmdComplete,OMX_CommandStateSet,
   1296                                          OMX_StateIdle,NULL);
   1297                 DEBUG_PRINT_LOW(" OMX_COMPONENT_GENERATE_STOP_DONE cb finished");
   1298               }
   1299             }
   1300           }
   1301           else
   1302           {
   1303             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1304           }
   1305 
   1306           break;
   1307 
   1308         case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1309           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
   1310 
   1311           if (p2 == OMX_IndexParamPortDefinition) {
   1312             pThis->in_reconfig = true;
   1313           }
   1314           if (pThis->m_cb.EventHandler) {
   1315             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1316                 OMX_EventPortSettingsChanged, p1, p2, NULL );
   1317           } else {
   1318             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1319           }
   1320 
   1321           if (pThis->drv_ctx.interlace != V4L2_FIELD_NONE/*VDPP_InterlaceFrameProgressive*/)
   1322           {
   1323             OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
   1324             OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
   1325             if (pThis->drv_ctx.interlace == V4L2_FIELD_INTERLACED_TB/*VDPP_InterlaceInterleaveFrameTopFieldFirst*/)
   1326                 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
   1327             else if (pThis->drv_ctx.interlace == V4L2_FIELD_INTERLACED_BT/*VDPP_InterlaceInterleaveFrameBottomFieldFirst*/)
   1328                 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   1329             else //unsupported interlace format; raise a error
   1330                 event = OMX_EventError;
   1331             if (pThis->m_cb.EventHandler) {
   1332               pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1333                   event, format, 0, NULL );
   1334             } else {
   1335               DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1336             }
   1337           }
   1338         break;
   1339 
   1340         case OMX_COMPONENT_GENERATE_EOS_DONE:
   1341           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1342           if (pThis->m_cb.EventHandler) {
   1343             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1344                             OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1345           } else {
   1346             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1347           }
   1348           pThis->prev_ts = LLONG_MAX;
   1349           pThis->rst_prev_ts = true;
   1350           break;
   1351 
   1352         case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1353           DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1354           pThis->omx_report_error ();
   1355           break;
   1356 
   1357         case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1358           DEBUG_PRINT_ERROR(" OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
   1359           pThis->omx_report_unsupported_setting();
   1360           break;
   1361 
   1362         case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
   1363         {
   1364           DEBUG_PRINT_HIGH(" Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
   1365           if (pThis->m_cb.EventHandler) {
   1366             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1367                 (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
   1368           } else {
   1369             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1370           }
   1371         }
   1372         // extensions
   1373         case OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS:
   1374         {
   1375           struct v4l2_rect * ar_result = (struct v4l2_rect *) p1;
   1376           QOMX_ACTIVEREGIONDETECTION_STATUSTYPE arstatus;
   1377           arstatus.nSize = sizeof(QOMX_ACTIVEREGIONDETECTION_STATUSTYPE);
   1378           arstatus.nPortIndex      = 0;
   1379           arstatus.bDetected = OMX_TRUE;
   1380           memcpy(&arstatus.sDetectedRegion, ar_result, sizeof(QOMX_RECTTYPE));
   1381           DEBUG_PRINT_HIGH(" OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS");
   1382           // data2 should be (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus
   1383           // pdata should be QOMX_ACTIVEREGIONDETECTION_STATUSTYPE
   1384           if (pThis->m_cb.EventHandler) {
   1385              pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1386                  (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus, &arstatus);
   1387           } else {
   1388             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1389           }
   1390         }
   1391         default:
   1392           break;
   1393         }
   1394       }
   1395     pthread_mutex_lock(&pThis->m_lock);
   1396     qsize = pThis->m_cmd_q.m_size;
   1397     if (pThis->m_state != OMX_StatePause)
   1398         qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1399     pthread_mutex_unlock(&pThis->m_lock);
   1400   }
   1401   while(qsize>0);
   1402 
   1403 }
   1404 
   1405 int omx_vdpp::update_resolution(uint32_t width, uint32_t height, uint32_t stride, uint32_t scan_lines)
   1406 {
   1407 	int format_changed = 0;
   1408 	if ((height != drv_ctx.video_resolution_input.frame_height) ||
   1409 		(width != drv_ctx.video_resolution_input.frame_width)) {
   1410 		DEBUG_PRINT_HIGH("NOTE: W/H %d (%d), %d (%d)\n",
   1411 			width, drv_ctx.video_resolution_input.frame_width,
   1412 			height,drv_ctx.video_resolution_input.frame_height);
   1413 		format_changed = 1;
   1414 	}
   1415     drv_ctx.video_resolution_input.frame_height = height;
   1416     drv_ctx.video_resolution_input.frame_width = width;
   1417     drv_ctx.video_resolution_input.scan_lines = scan_lines;
   1418     drv_ctx.video_resolution_input.stride = stride;
   1419     rectangle.nLeft = 0;
   1420     rectangle.nTop = 0;
   1421     rectangle.nWidth = drv_ctx.video_resolution_input.frame_width;
   1422     rectangle.nHeight = drv_ctx.video_resolution_input.frame_height;
   1423     return format_changed;
   1424 }
   1425 
   1426 /* ======================================================================
   1427 FUNCTION
   1428   omx_vdpp::ComponentInit
   1429 
   1430 DESCRIPTION
   1431   Initialize the component.
   1432 
   1433 PARAMETERS
   1434   ctxt -- Context information related to the self.
   1435   id   -- Event identifier. This could be any of the following:
   1436           1. Command completion event
   1437           2. Buffer done callback event
   1438           3. Frame done callback event
   1439 
   1440 RETURN VALUE
   1441   None.
   1442 
   1443 ========================================================================== */
   1444 OMX_ERRORTYPE omx_vdpp::component_init(OMX_STRING role)
   1445 {
   1446 
   1447 	OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1448 	struct v4l2_format fmt;
   1449 	int fds[2];
   1450     int fctl[2];
   1451 	int ret=0;
   1452     int i = 0;
   1453     int sessionNum = 0;
   1454 
   1455     errno = 0;
   1456 
   1457 #ifndef STUB_VPU
   1458 	drv_ctx.video_vpu_fd = openInput("msm_vpu");
   1459 #else
   1460     drv_ctx.video_vpu_fd = 1;
   1461 #endif
   1462 	DEBUG_PRINT_HIGH(" omx_vdpp::component_init(): Open returned fd %d, errno %d",
   1463 			drv_ctx.video_vpu_fd, errno);
   1464 
   1465 	if(drv_ctx.video_vpu_fd == 0){
   1466 	    DEBUG_PRINT_ERROR("omx_vdpp:: Got fd as 0 for vpu, Opening again\n");
   1467 	    drv_ctx.video_vpu_fd = openInput("msm_vpu");
   1468 	}
   1469 
   1470 	if(drv_ctx.video_vpu_fd < 0)
   1471 	{
   1472 		DEBUG_PRINT_ERROR("omx_vdpp::Comp Init Returning failure, errno %d\n", errno);
   1473 		return OMX_ErrorInsufficientResources;
   1474 	}
   1475 
   1476 #ifndef STUB_VPU
   1477     // query number of sessions and attach to session #1
   1478     /* Check how many sessions are suported by H/W */
   1479     ret = ioctl(drv_ctx.video_vpu_fd, VPU_QUERY_SESSIONS,
   1480 				&drv_ctx.sessionsSupported);
   1481     if (ret < 0)
   1482     {
   1483         DEBUG_PRINT_ERROR("QUERY_SESSIONS: VPU_QUERY_SESSIONS failed.");
   1484         close(drv_ctx.video_vpu_fd);
   1485         drv_ctx.video_vpu_fd = 0;
   1486         return OMX_ErrorInsufficientResources;
   1487     }
   1488     else
   1489     {
   1490         DEBUG_PRINT_HIGH("QUERY_SESSIONS: The number of sessions supported are %d.",
   1491              drv_ctx.sessionsSupported);
   1492     }
   1493 #endif
   1494 
   1495     /* Attach Client to Session. */
   1496     sessionNum = VDPP_SESSION;
   1497 
   1498 #ifndef STUB_VPU
   1499     ret = ioctl(drv_ctx.video_vpu_fd, VPU_ATTACH_TO_SESSION, &sessionNum);
   1500     if (ret < 0)
   1501     {
   1502         if( errno == EINVAL )
   1503             DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: session %d is out of valid "
   1504 			"range.", sessionNum);
   1505         else if( errno == EBUSY)
   1506             DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: max. allowed number of"
   1507                     "clients attached to session.");
   1508         else
   1509             DEBUG_PRINT_ERROR("VPU_ATTACH_TO_SESSION: failed for unknown reason.");
   1510         return OMX_ErrorUndefined;
   1511     }
   1512     else
   1513     {
   1514         DEBUG_PRINT_HIGH("VPU_ATTACH_TO_SESSION: client successfully attached "
   1515 		"to session.");
   1516     }
   1517 #endif
   1518     drv_ctx.sessionAttached = sessionNum;
   1519 
   1520 	drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   1521 	drv_ctx.frame_rate.fps_denominator = 1;
   1522 
   1523     ret = subscribe_to_events(drv_ctx.video_vpu_fd);
   1524 
   1525     /* create control pipes */
   1526     if (!ret)
   1527     {
   1528 	    if(pipe(fctl))
   1529 	    {
   1530 		    DEBUG_PRINT_ERROR("pipe creation failed\n");
   1531 		    eRet = OMX_ErrorInsufficientResources;
   1532 	    }
   1533 	    else
   1534 	    {
   1535 		    int temp2[2];
   1536 		    if(fctl[0] == 0 || fctl[1] == 0)
   1537 		    {
   1538 			    if (pipe (temp2))
   1539 			    {
   1540 				    DEBUG_PRINT_ERROR("pipe creation failed\n");
   1541 				    return OMX_ErrorInsufficientResources;
   1542 			    }
   1543 			    fctl[0] = temp2 [0];
   1544 			    fctl[1] = temp2 [1];
   1545 		    }
   1546 		    m_ctrl_in = fctl[0];
   1547 		    m_ctrl_out = fctl[1];
   1548 
   1549             fcntl(m_ctrl_in, F_SETFL, O_NONBLOCK);
   1550             fcntl(m_ctrl_out, F_SETFL, O_NONBLOCK);
   1551         }
   1552     }
   1553 
   1554     if (!ret) {
   1555       async_thread_created = true;
   1556       ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   1557 	}
   1558     if(ret) {
   1559 	  DEBUG_PRINT_ERROR(" Failed to create async_message_thread \n");
   1560 	  async_thread_created = false;
   1561 	  return OMX_ErrorInsufficientResources;
   1562     }
   1563 
   1564 #ifdef INPUT_BUFFER_LOG
   1565 	inputBufferFile = open(inputfilename,  O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
   1566     if(inputBufferFile < 0)
   1567     {
   1568 	  DEBUG_PRINT_ERROR(" Failed to create inputBufferFile 0, errno = %d\n", errno);
   1569     }
   1570 
   1571 #endif
   1572 
   1573 #ifdef OUTPUT_BUFFER_LOG
   1574 	outputBufferFile = open(outputfilename,  O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
   1575     if(outputBufferFile < 0)
   1576     {
   1577 	  DEBUG_PRINT_ERROR(" Failed to create outputBufferFile 0 , errno = %d\n", errno);
   1578     }
   1579 #endif
   1580 
   1581 #ifdef OUTPUT_EXTRADATA_LOG
   1582 	outputExtradataFile = open (ouputextradatafilename, O_CREAT|O_WRONLY|O_TRUNC, S_IRUSR | S_IWUSR);
   1583     if(outputExtradataFile == -1)
   1584     {
   1585 	  DEBUG_PRINT_ERROR(" Failed to create outputExtradataFile , errno = %d\n", errno);
   1586     }
   1587 #endif
   1588 
   1589 	// Copy the role information which provides the vdpp kind
   1590 	strlcpy(drv_ctx.kind,role,128);
   1591 
   1592     // Default set to progressive mode for 8084. drv_ctx.interlace will be changed by
   1593     // interlace format filed of OMX buffer header extra data. User can also overwrite
   1594     // this setting by OMX_IndexParamInterlaceFormat
   1595     drv_ctx.interlace = V4L2_FIELD_NONE;
   1596 
   1597     // Default input pixel format
   1598     output_capability=V4L2_PIX_FMT_NV12;
   1599 
   1600 	if (eRet == OMX_ErrorNone)
   1601 	{
   1602         // set default output format to V4L2_PIX_FMT_NV12. User can use SetParam
   1603         // with OMX_IndexParamVideoPortFormat to set vdpp output format
   1604 		drv_ctx.output_format = V4L2_PIX_FMT_NV12;
   1605 		capture_capability    = V4L2_PIX_FMT_NV12;
   1606 
   1607 		struct v4l2_capability cap;
   1608 #ifndef STUB_VPU
   1609 		ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QUERYCAP, &cap);
   1610 		if (ret) {
   1611 		            DEBUG_PRINT_ERROR("Failed to query capabilities\n");
   1612 				    return OMX_ErrorUndefined;
   1613 		} else {
   1614 		        DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   1615 				" version = %d, capabilities = %x\n", cap.driver, cap.card,
   1616 				cap.bus_info, cap.version, cap.capabilities);
   1617 
   1618             if ((cap.capabilities & V4L2_CAP_STREAMING) == 0)
   1619             {
   1620                 DEBUG_PRINT_ERROR("device does not support streaming i/o\n");
   1621 				return OMX_ErrorInsufficientResources;
   1622             }
   1623 		}
   1624 #endif
   1625         // set initial input h/w and pixel format
   1626         update_resolution(640, 480, 640, 480);
   1627 
   1628 		fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1629 		fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
   1630 		fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
   1631         if (V4L2_FIELD_NONE == drv_ctx.interlace)
   1632         {
   1633             fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   1634         }
   1635         else
   1636         {
   1637 		fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
   1638         }
   1639 		fmt.fmt.pix_mp.pixelformat = output_capability;
   1640 
   1641         // NV12 has 2 planes.
   1642         /* Set format for each plane. */
   1643         setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   1644         for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   1645         {
   1646             fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[i] * fmt.fmt.pix_mp.height);
   1647             fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // NV12 UV plane has the same width as Y, but 1/2 YH
   1648             DEBUG_PRINT_HIGH(" fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   1649         }
   1650 #ifndef STUB_VPU
   1651 		ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   1652 
   1653 		if (ret) {
   1654 			        DEBUG_PRINT_ERROR("Failed to set format on output port\n");
   1655 				    return OMX_ErrorUndefined;
   1656 				}
   1657 		DEBUG_PRINT_HIGH(" Set Format was successful drv_ctx.interlace = %d\n ", drv_ctx.interlace);
   1658 #endif
   1659         // set initial output format
   1660         // initial input/output resolution are the same. portdefinition changes both
   1661         memset(&fmt, 0, sizeof(fmt));
   1662 
   1663 		fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1664 		fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
   1665 		fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
   1666 	    fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   1667 		fmt.fmt.pix_mp.pixelformat = capture_capability;
   1668         DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d", fmt.fmt.pix_mp.width,
   1669                 fmt.fmt.pix_mp.height);
   1670 
   1671         setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   1672         for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   1673         {
   1674             fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
   1675                                                                         drv_ctx.output_bytesperpixel[i] *
   1676                                                                         fmt.fmt.pix_mp.height);
   1677             fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
   1678             DEBUG_PRINT_HIGH(" fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   1679         }
   1680 #ifndef STUB_VPU
   1681         ret  = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   1682         if (ret < 0)
   1683         {
   1684             DEBUG_PRINT_ERROR("VIDIOC_S_FMT setup VP output format error");
   1685             return OMX_ErrorUndefined;
   1686         }
   1687 #endif
   1688         // update initial output resolution
   1689         drv_ctx.video_resolution_output.frame_height = fmt.fmt.pix_mp.height;
   1690         drv_ctx.video_resolution_output.frame_width = fmt.fmt.pix_mp.width;
   1691         drv_ctx.video_resolution_output.scan_lines = fmt.fmt.pix_mp.height;
   1692         drv_ctx.video_resolution_output.stride = fmt.fmt.pix_mp.width;
   1693 
   1694 		if (ret) {
   1695 			        DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
   1696                     return OMX_ErrorUndefined;
   1697 				}
   1698 		DEBUG_PRINT_HIGH(" Set Format was successful \n ");
   1699 
   1700 		/*Get the Buffer requirements for input and output ports*/
   1701 		drv_ctx.ip_buf.buffer_type = VDPP_BUFFER_TYPE_INPUT;
   1702 		drv_ctx.op_buf.buffer_type = VDPP_BUFFER_TYPE_OUTPUT;
   1703 
   1704 		drv_ctx.op_buf.alignment=SZ_4K;
   1705 		drv_ctx.ip_buf.alignment=SZ_4K;
   1706 
   1707         m_state = OMX_StateLoaded;
   1708 
   1709         eRet=get_buffer_req(&drv_ctx.ip_buf);
   1710         DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
   1711         get_buffer_req(&drv_ctx.op_buf);
   1712 
   1713         /* create pipes for message thread*/
   1714 		if(pipe(fds))
   1715 		{
   1716 			DEBUG_PRINT_ERROR("pipe creation failed\n");
   1717 			eRet = OMX_ErrorInsufficientResources;
   1718 		}
   1719 		else
   1720 		{
   1721 			int temp1[2];
   1722 			if(fds[0] == 0 || fds[1] == 0)
   1723 			{
   1724 				if (pipe (temp1))
   1725 				{
   1726 					DEBUG_PRINT_ERROR("pipe creation failed\n");
   1727 					return OMX_ErrorInsufficientResources;
   1728 				}
   1729 				fds[0] = temp1 [0];
   1730 				fds[1] = temp1 [1];
   1731 			}
   1732 			m_pipe_in = fds[0];
   1733 			m_pipe_out = fds[1];
   1734 			msg_thread_created = true;
   1735 			ret = pthread_create(&msg_thread_id,0,message_thread,this);
   1736 
   1737 			if(ret < 0)
   1738 			{
   1739 				DEBUG_PRINT_ERROR(" component_init(): message_thread creation failed");
   1740 				msg_thread_created = false;
   1741 				eRet = OMX_ErrorInsufficientResources;
   1742 			}
   1743 		}
   1744 	}
   1745 
   1746 	if (eRet != OMX_ErrorNone)
   1747 	{
   1748 		DEBUG_PRINT_ERROR(" Component Init Failed");
   1749 	}
   1750 	else
   1751 	{
   1752 		DEBUG_PRINT_HIGH(" omx_vdpp::component_init() success");
   1753 	}
   1754 
   1755 	return eRet;
   1756 }
   1757 
   1758 /* ======================================================================
   1759 FUNCTION
   1760   omx_vdpp::GetComponentVersion
   1761 
   1762 DESCRIPTION
   1763   Returns the component version.
   1764 
   1765 PARAMETERS
   1766   TBD.
   1767 
   1768 RETURN VALUE
   1769   OMX_ErrorNone.
   1770 
   1771 ========================================================================== */
   1772 OMX_ERRORTYPE  omx_vdpp::get_component_version
   1773                                      (
   1774                                       OMX_IN OMX_HANDLETYPE hComp,
   1775                                       OMX_OUT OMX_STRING componentName,
   1776                                       OMX_OUT OMX_VERSIONTYPE* componentVersion,
   1777                                       OMX_OUT OMX_VERSIONTYPE* specVersion,
   1778                                       OMX_OUT OMX_UUIDTYPE* componentUUID
   1779                                       )
   1780 {
   1781     if(m_state == OMX_StateInvalid)
   1782     {
   1783         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
   1784         return OMX_ErrorInvalidState;
   1785     }
   1786   /* TBD -- Return the proper version */
   1787   if (specVersion)
   1788   {
   1789     specVersion->nVersion = OMX_SPEC_VERSION;
   1790   }
   1791   return OMX_ErrorNone;
   1792 }
   1793 /* ======================================================================
   1794 FUNCTION
   1795   omx_vdpp::SendCommand
   1796 
   1797 DESCRIPTION
   1798   Returns zero if all the buffers released..
   1799 
   1800 PARAMETERS
   1801   None.
   1802 
   1803 RETURN VALUE
   1804   true/false
   1805 
   1806 ========================================================================== */
   1807 OMX_ERRORTYPE  omx_vdpp::send_command(OMX_IN OMX_HANDLETYPE hComp,
   1808                                       OMX_IN OMX_COMMANDTYPE cmd,
   1809                                       OMX_IN OMX_U32 param1,
   1810                                       OMX_IN OMX_PTR cmdData
   1811                                       )
   1812 {
   1813     DEBUG_PRINT_LOW(" send_command: Recieved a Command from Client cmd = %d", cmd);
   1814     if(m_state == OMX_StateInvalid)
   1815     {
   1816         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
   1817         return OMX_ErrorInvalidState;
   1818     }
   1819     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   1820       && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL)
   1821     {
   1822       DEBUG_PRINT_ERROR(" send_command(): ERROR OMX_CommandFlush "
   1823         "to invalid port: %lu", param1);
   1824       return OMX_ErrorBadPortIndex;
   1825     }
   1826     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   1827     sem_wait(&m_cmd_lock);
   1828     DEBUG_PRINT_LOW(" send_command: Command Processed cmd = %d\n", cmd);
   1829     return OMX_ErrorNone;
   1830 }
   1831 
   1832 /* ======================================================================
   1833 FUNCTION
   1834   omx_vdpp::SendCommand
   1835 
   1836 DESCRIPTION
   1837   Returns zero if all the buffers released..
   1838 
   1839 PARAMETERS
   1840   None.
   1841 
   1842 RETURN VALUE
   1843   true/false
   1844 
   1845 ========================================================================== */
   1846 OMX_ERRORTYPE  omx_vdpp::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   1847                                             OMX_IN OMX_COMMANDTYPE cmd,
   1848                                             OMX_IN OMX_U32 param1,
   1849                                             OMX_IN OMX_PTR cmdData
   1850                                             )
   1851 {
   1852   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1853   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   1854   int bFlag = 1,sem_posted = 0,ret=0;
   1855 
   1856   DEBUG_PRINT_LOW(" send_command_proxy(): cmd = %d", cmd);
   1857   DEBUG_PRINT_HIGH("end_command_proxy(): Current State %d, Expected State %d",
   1858     m_state, eState);
   1859 
   1860   if(cmd == OMX_CommandStateSet)
   1861   {
   1862     DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   1863     DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   1864     /***************************/
   1865     /* Current State is Loaded */
   1866     /***************************/
   1867     if(m_state == OMX_StateLoaded)
   1868     {
   1869       if(eState == OMX_StateIdle)
   1870       {
   1871         //if all buffers are allocated or all ports disabled
   1872         if(allocate_done() ||
   1873           (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE))
   1874         {
   1875           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
   1876         }
   1877         else
   1878         {
   1879           DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending\n");
   1880           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   1881           // Skip the event notification
   1882           bFlag = 0;
   1883         }
   1884       }
   1885       /* Requesting transition from Loaded to Loaded */
   1886       else if(eState == OMX_StateLoaded)
   1887       {
   1888         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
   1889         post_event(OMX_EventError,OMX_ErrorSameState,\
   1890                    OMX_COMPONENT_GENERATE_EVENT);
   1891         eRet = OMX_ErrorSameState;
   1892       }
   1893       /* Requesting transition from Loaded to WaitForResources */
   1894       else if(eState == OMX_StateWaitForResources)
   1895       {
   1896         /* Since error is None , we will post an event
   1897            at the end of this function definition */
   1898         DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
   1899       }
   1900       /* Requesting transition from Loaded to Executing */
   1901       else if(eState == OMX_StateExecuting)
   1902       {
   1903         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
   1904         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1905                    OMX_COMPONENT_GENERATE_EVENT);
   1906         eRet = OMX_ErrorIncorrectStateTransition;
   1907       }
   1908       /* Requesting transition from Loaded to Pause */
   1909       else if(eState == OMX_StatePause)
   1910       {
   1911         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
   1912         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1913                    OMX_COMPONENT_GENERATE_EVENT);
   1914         eRet = OMX_ErrorIncorrectStateTransition;
   1915       }
   1916       /* Requesting transition from Loaded to Invalid */
   1917       else if(eState == OMX_StateInvalid)
   1918       {
   1919         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
   1920         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1921         eRet = OMX_ErrorInvalidState;
   1922       }
   1923       else
   1924       {
   1925         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
   1926                           eState);
   1927         eRet = OMX_ErrorBadParameter;
   1928       }
   1929     }
   1930 
   1931     /***************************/
   1932     /* Current State is IDLE */
   1933     /***************************/
   1934     else if(m_state == OMX_StateIdle)
   1935     {
   1936       if(eState == OMX_StateLoaded)
   1937       {
   1938         if(release_done())
   1939         {
   1940           /*
   1941              Since error is None , we will post an event at the end
   1942              of this function definition
   1943           */
   1944           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
   1945         }
   1946         else
   1947         {
   1948           DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
   1949           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   1950           // Skip the event notification
   1951           bFlag = 0;
   1952         }
   1953       }
   1954       /* Requesting transition from Idle to Executing */
   1955       else if(eState == OMX_StateExecuting)
   1956       {
   1957 	    DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   1958         //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   1959         bFlag = 1;
   1960 	    m_state=OMX_StateExecuting;
   1961 	    DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
   1962       }
   1963       /* Requesting transition from Idle to Idle */
   1964       else if(eState == OMX_StateIdle)
   1965       {
   1966         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
   1967         post_event(OMX_EventError,OMX_ErrorSameState,\
   1968                    OMX_COMPONENT_GENERATE_EVENT);
   1969         eRet = OMX_ErrorSameState;
   1970       }
   1971       /* Requesting transition from Idle to WaitForResources */
   1972       else if(eState == OMX_StateWaitForResources)
   1973       {
   1974         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
   1975         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1976                    OMX_COMPONENT_GENERATE_EVENT);
   1977         eRet = OMX_ErrorIncorrectStateTransition;
   1978       }
   1979        /* Requesting transition from Idle to Pause */
   1980        else if(eState == OMX_StatePause)
   1981       {
   1982          /*To pause the Video core we need to start the driver*/
   1983          if (/*ioctl (drv_ctx.video_vpu_fd,VDPP_IOCTL_CMD_START,
   1984                     NULL) < */0)
   1985          {
   1986            DEBUG_PRINT_ERROR(" VDPP_IOCTL_CMD_START FAILED");
   1987            omx_report_error ();
   1988            eRet = OMX_ErrorHardware;
   1989          }
   1990          else
   1991          {
   1992            BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   1993            DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
   1994            bFlag = 0;
   1995          }
   1996       }
   1997       /* Requesting transition from Idle to Invalid */
   1998        else if(eState == OMX_StateInvalid)
   1999       {
   2000         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
   2001         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2002         eRet = OMX_ErrorInvalidState;
   2003       }
   2004       else
   2005       {
   2006         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
   2007         eRet = OMX_ErrorBadParameter;
   2008       }
   2009     }
   2010 
   2011     /******************************/
   2012     /* Current State is Executing */
   2013     /******************************/
   2014     else if(m_state == OMX_StateExecuting)
   2015     {
   2016        DEBUG_PRINT_LOW(" Command Recieved in OMX_StateExecuting");
   2017        /* Requesting transition from Executing to Idle */
   2018        if(eState == OMX_StateIdle)
   2019 	   {
   2020 		   /* Since error is None , we will post an event
   2021 			  at the end of this function definition
   2022 			*/
   2023 		   DEBUG_PRINT_LOW(" send_command_proxy(): Executing --> Idle \n");
   2024 		   BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2025 		   if(!sem_posted)
   2026 		   {
   2027 			   sem_posted = 1;
   2028 			   sem_post (&m_cmd_lock);
   2029 			   execute_omx_flush(OMX_ALL);
   2030 		   }
   2031 		   bFlag = 0;
   2032 	   }
   2033        /* Requesting transition from Executing to Paused */
   2034        else if(eState == OMX_StatePause)
   2035        {
   2036          DEBUG_PRINT_LOW(" PAUSE Command Issued");
   2037          m_state = OMX_StatePause;
   2038          bFlag = 1;
   2039        }
   2040        /* Requesting transition from Executing to Loaded */
   2041        else if(eState == OMX_StateLoaded)
   2042        {
   2043          DEBUG_PRINT_ERROR(" send_command_proxy(): Executing --> Loaded \n");
   2044          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2045                     OMX_COMPONENT_GENERATE_EVENT);
   2046          eRet = OMX_ErrorIncorrectStateTransition;
   2047        }
   2048        /* Requesting transition from Executing to WaitForResources */
   2049        else if(eState == OMX_StateWaitForResources)
   2050        {
   2051          DEBUG_PRINT_ERROR(" send_command_proxy(): Executing --> WaitForResources \n");
   2052          post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2053                     OMX_COMPONENT_GENERATE_EVENT);
   2054          eRet = OMX_ErrorIncorrectStateTransition;
   2055        }
   2056        /* Requesting transition from Executing to Executing */
   2057        else if(eState == OMX_StateExecuting)
   2058        {
   2059          DEBUG_PRINT_ERROR(" send_command_proxy(): Executing --> Executing \n");
   2060          post_event(OMX_EventError,OMX_ErrorSameState,\
   2061                     OMX_COMPONENT_GENERATE_EVENT);
   2062          eRet = OMX_ErrorSameState;
   2063        }
   2064        /* Requesting transition from Executing to Invalid */
   2065        else if(eState == OMX_StateInvalid)
   2066        {
   2067          DEBUG_PRINT_ERROR(" send_command_proxy(): Executing --> Invalid \n");
   2068          post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2069          eRet = OMX_ErrorInvalidState;
   2070        }
   2071        else
   2072        {
   2073          DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
   2074          eRet = OMX_ErrorBadParameter;
   2075        }
   2076     }
   2077     /***************************/
   2078     /* Current State is Pause  */
   2079     /***************************/
   2080     else if(m_state == OMX_StatePause)
   2081     {
   2082       /* Requesting transition from Pause to Executing */
   2083       if(eState == OMX_StateExecuting)
   2084       {
   2085         DEBUG_PRINT_LOW(" Pause --> Executing \n");
   2086         m_state = OMX_StateExecuting;
   2087         bFlag = 1;
   2088       }
   2089       /* Requesting transition from Pause to Idle */
   2090       else if(eState == OMX_StateIdle)
   2091       {
   2092         /* Since error is None , we will post an event
   2093         at the end of this function definition */
   2094         DEBUG_PRINT_LOW(" Pause --> Idle \n");
   2095          BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2096          if(!sem_posted)
   2097          {
   2098            sem_posted = 1;
   2099            sem_post (&m_cmd_lock);
   2100            execute_omx_flush(OMX_ALL);
   2101          }
   2102          bFlag = 0;
   2103       }
   2104       /* Requesting transition from Pause to loaded */
   2105       else if(eState == OMX_StateLoaded)
   2106       {
   2107         DEBUG_PRINT_ERROR(" Pause --> loaded \n");
   2108         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2109                    OMX_COMPONENT_GENERATE_EVENT);
   2110         eRet = OMX_ErrorIncorrectStateTransition;
   2111       }
   2112       /* Requesting transition from Pause to WaitForResources */
   2113       else if(eState == OMX_StateWaitForResources)
   2114       {
   2115         DEBUG_PRINT_ERROR(" Pause --> WaitForResources \n");
   2116         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2117                    OMX_COMPONENT_GENERATE_EVENT);
   2118         eRet = OMX_ErrorIncorrectStateTransition;
   2119       }
   2120       /* Requesting transition from Pause to Pause */
   2121       else if(eState == OMX_StatePause)
   2122       {
   2123         DEBUG_PRINT_ERROR(" Pause --> Pause \n");
   2124         post_event(OMX_EventError,OMX_ErrorSameState,\
   2125                    OMX_COMPONENT_GENERATE_EVENT);
   2126         eRet = OMX_ErrorSameState;
   2127       }
   2128        /* Requesting transition from Pause to Invalid */
   2129       else if(eState == OMX_StateInvalid)
   2130       {
   2131         DEBUG_PRINT_ERROR(" Pause --> Invalid \n");
   2132         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2133         eRet = OMX_ErrorInvalidState;
   2134       }
   2135       else
   2136       {
   2137         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
   2138         eRet = OMX_ErrorBadParameter;
   2139       }
   2140     }
   2141      /***************************/
   2142     /* Current State is WaitForResources  */
   2143     /***************************/
   2144     else if(m_state == OMX_StateWaitForResources)
   2145     {
   2146       /* Requesting transition from WaitForResources to Loaded */
   2147       if(eState == OMX_StateLoaded)
   2148       {
   2149         /* Since error is None , we will post an event
   2150         at the end of this function definition */
   2151         DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
   2152       }
   2153       /* Requesting transition from WaitForResources to WaitForResources */
   2154       else if (eState == OMX_StateWaitForResources)
   2155       {
   2156         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
   2157         post_event(OMX_EventError,OMX_ErrorSameState,
   2158                    OMX_COMPONENT_GENERATE_EVENT);
   2159         eRet = OMX_ErrorSameState;
   2160       }
   2161       /* Requesting transition from WaitForResources to Executing */
   2162       else if(eState == OMX_StateExecuting)
   2163       {
   2164         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
   2165         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2166                    OMX_COMPONENT_GENERATE_EVENT);
   2167         eRet = OMX_ErrorIncorrectStateTransition;
   2168       }
   2169       /* Requesting transition from WaitForResources to Pause */
   2170       else if(eState == OMX_StatePause)
   2171       {
   2172         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
   2173         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2174                    OMX_COMPONENT_GENERATE_EVENT);
   2175         eRet = OMX_ErrorIncorrectStateTransition;
   2176       }
   2177       /* Requesting transition from WaitForResources to Invalid */
   2178       else if(eState == OMX_StateInvalid)
   2179       {
   2180         DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
   2181         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2182         eRet = OMX_ErrorInvalidState;
   2183       }
   2184       /* Requesting transition from WaitForResources to Loaded -
   2185       is NOT tested by Khronos TS */
   2186 
   2187     }
   2188     else
   2189     {
   2190       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
   2191       eRet = OMX_ErrorBadParameter;
   2192     }
   2193   }
   2194   /********************************/
   2195   /* Current State is Invalid */
   2196   /*******************************/
   2197   else if(m_state == OMX_StateInvalid)
   2198   {
   2199     /* State Transition from Inavlid to any state */
   2200     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
   2201                   || OMX_StateIdle || OMX_StateExecuting
   2202                   || OMX_StatePause || OMX_StateInvalid))
   2203     {
   2204       DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
   2205       post_event(OMX_EventError,OMX_ErrorInvalidState,\
   2206                  OMX_COMPONENT_GENERATE_EVENT);
   2207       eRet = OMX_ErrorInvalidState;
   2208     }
   2209   }
   2210   else if (cmd == OMX_CommandFlush)
   2211   {
   2212     DEBUG_PRINT_HIGH(" send_command_proxy(): OMX_CommandFlush issued "
   2213         "with param1: 0x%x", param1);
   2214     if(OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1)
   2215     {   // do not call flush ioctl if there is no buffer queued. Just return callback
   2216 #ifndef STUB_VPU // VPU stub doesn't set any streaming flag
   2217         if(!streaming[OUTPUT_PORT])
   2218         {
   2219             m_cb.EventHandler(&m_cmp, m_app_data, OMX_EventCmdComplete,OMX_CommandFlush,
   2220                                                OMX_CORE_INPUT_PORT_INDEX,NULL );
   2221             sem_posted = 1;
   2222             sem_post (&m_cmd_lock);
   2223         }
   2224         else
   2225 #endif
   2226         {
   2227             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   2228         }
   2229     }
   2230     if(OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1)
   2231     {
   2232       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   2233     }
   2234     if (!sem_posted){
   2235       sem_posted = 1;
   2236       DEBUG_PRINT_LOW(" Set the Semaphore");
   2237       sem_post (&m_cmd_lock);
   2238       execute_omx_flush(param1);
   2239     }
   2240     bFlag = 0;
   2241   }
   2242   else if ( cmd == OMX_CommandPortEnable)
   2243   {
   2244     DEBUG_PRINT_HIGH(" send_command_proxy(): OMX_CommandPortEnable issued "
   2245         "with param1: %lu", param1);
   2246     if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
   2247       {
   2248         m_inp_bEnabled = OMX_TRUE;
   2249 
   2250         if( (m_state == OMX_StateLoaded &&
   2251              !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2252             || allocate_input_done())
   2253         {
   2254           post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   2255                      OMX_COMPONENT_GENERATE_EVENT);
   2256         }
   2257         else
   2258         {
   2259           DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   2260           BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2261           // Skip the event notification
   2262           bFlag = 0;
   2263         }
   2264       }
   2265       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
   2266       {
   2267           DEBUG_PRINT_LOW(" Enable output Port command recieved");
   2268           m_out_bEnabled = OMX_TRUE;
   2269 
   2270           if( (m_state == OMX_StateLoaded &&
   2271               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2272               || (allocate_output_done()))
   2273           {
   2274              post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   2275                         OMX_COMPONENT_GENERATE_EVENT);
   2276 
   2277           }
   2278           else
   2279           {
   2280               DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   2281               BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2282               // Skip the event notification
   2283               bFlag = 0;
   2284           }
   2285       }
   2286   }
   2287   else if (cmd == OMX_CommandPortDisable)
   2288   {
   2289       DEBUG_PRINT_HIGH(" send_command_proxy(): OMX_CommandPortDisable issued"
   2290           "with param1: %lu m_state = %d, streaming[OUTPUT_PORT] = %d", param1, m_state, streaming[OUTPUT_PORT]);
   2291       if(param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL)
   2292       {
   2293           m_inp_bEnabled = OMX_FALSE;
   2294           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2295               && release_input_done())
   2296           {
   2297              post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   2298                         OMX_COMPONENT_GENERATE_EVENT);
   2299              DEBUG_PRINT_LOW("OMX_CommandPortDisable 1");
   2300           }
   2301           else
   2302           {
   2303              BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   2304              DEBUG_PRINT_LOW("OMX_CommandPortDisable 2");
   2305              if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   2306              {
   2307                if(!sem_posted)
   2308                {
   2309                  sem_posted = 1;
   2310                  sem_post (&m_cmd_lock);
   2311                }
   2312                if(!streaming[OUTPUT_PORT])
   2313                {
   2314                     DEBUG_PRINT_LOW("OMX_CommandPortDisable 3 ");
   2315                     //IL client calls disable port and then free buffers.
   2316                     //from free buffer, disable port done event will be sent
   2317                }
   2318                else
   2319                {
   2320                    execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   2321                }
   2322              }
   2323 
   2324              // Skip the event notification
   2325              bFlag = 0;
   2326           }
   2327       }
   2328       if(param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL)
   2329       {
   2330           m_out_bEnabled = OMX_FALSE;
   2331           DEBUG_PRINT_LOW(" Disable output Port command recieved m_state = %d", m_state);
   2332           if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2333               && release_output_done())
   2334           {
   2335              post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   2336                         OMX_COMPONENT_GENERATE_EVENT);
   2337           }
   2338           else
   2339          {
   2340             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   2341             if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
   2342             {
   2343               if (!sem_posted)
   2344               {
   2345                 sem_posted = 1;
   2346                 sem_post (&m_cmd_lock);
   2347               }
   2348                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   2349                 execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   2350             }
   2351             // Skip the event notification
   2352             bFlag = 0;
   2353 
   2354          }
   2355       }
   2356   }
   2357   else
   2358   {
   2359     DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
   2360     eRet = OMX_ErrorNotImplemented;
   2361   }
   2362   if(eRet == OMX_ErrorNone && bFlag)
   2363   {
   2364     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   2365   }
   2366   if(!sem_posted)
   2367   {
   2368     sem_post(&m_cmd_lock);
   2369   }
   2370 
   2371   return eRet;
   2372 }
   2373 
   2374 /* ======================================================================
   2375 FUNCTION
   2376   omx_vdpp::ExecuteOmxFlush
   2377 
   2378 DESCRIPTION
   2379   Executes the OMX flush.
   2380 
   2381 PARAMETERS
   2382   flushtype - input flush(1)/output flush(0)/ both.
   2383 
   2384 RETURN VALUE
   2385   true/false
   2386 
   2387 ========================================================================== */
   2388 bool omx_vdpp::execute_omx_flush(OMX_U32 flushType)
   2389 {
   2390   bool bRet = false;
   2391   struct v4l2_requestbuffers bufreq;
   2392   struct vdpp_msginfo vdpp_msg;
   2393   enum v4l2_buf_type buf_type;
   2394   unsigned i = 0;
   2395 
   2396   DEBUG_PRINT_LOW("in %s flushType = %d", __func__, flushType);
   2397   memset((void *)&vdpp_msg,0,sizeof(vdpp_msg));
   2398 
   2399   switch (flushType)
   2400   {
   2401     case OMX_CORE_INPUT_PORT_INDEX:
   2402       input_flush_progress = true;
   2403 
   2404     break;
   2405     case OMX_CORE_OUTPUT_PORT_INDEX:
   2406       output_flush_progress = true;
   2407 
   2408     break;
   2409     default:
   2410       input_flush_progress = true;
   2411       output_flush_progress = true;
   2412   }
   2413 
   2414   DEBUG_PRINT_HIGH("omx_vdpp::execute_omx_flush m_ftb_q.m_size = %d, m_etb_q.m_size = %d\n", m_ftb_q.m_size, m_etb_q.m_size);
   2415   // vpu doesn't have flush right now, simulate flush done from here
   2416 #ifdef STUB_VPU
   2417   {
   2418     // dq output
   2419     if(output_flush_progress)
   2420     {
   2421 	  vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_OUTPUT_DONE;
   2422 	  vdpp_msg.status_code=VDPP_S_SUCCESS;
   2423 	  DEBUG_PRINT_HIGH("Simulate VDPP Output Flush Done Recieved From Driver\n");
   2424 	  if (async_message_process(this,&vdpp_msg) < 0) {
   2425 		    DEBUG_PRINT_HIGH(" VDPP Output Flush Done returns < 0  \n");
   2426 	  }
   2427     }
   2428 
   2429     // dq input
   2430     if(input_flush_progress)
   2431     {
   2432 	  vdpp_msg.msgcode=VDPP_MSG_RESP_FLUSH_INPUT_DONE;
   2433 	  vdpp_msg.status_code=VDPP_S_SUCCESS;
   2434 	  DEBUG_PRINT_HIGH("Simulate VDPP Input Flush Done Recieved From Driver \n");
   2435 	  if (async_message_process(this,&vdpp_msg) < 0) {
   2436 		    DEBUG_PRINT_HIGH(" VDPP Input Flush Done returns < 0  \n");
   2437 	  }
   2438 
   2439     }
   2440 
   2441   }
   2442 #else
   2443     // flush input port
   2444     if(input_flush_progress)
   2445     {
   2446 		buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2447 
   2448 		if(ioctl(drv_ctx.video_vpu_fd, VPU_FLUSH_BUFS, &buf_type))
   2449         {
   2450            DEBUG_PRINT_ERROR("VDPP input Flush error! \n");
   2451            return false;
   2452         }
   2453         else
   2454         {
   2455             DEBUG_PRINT_LOW("VDPP input Flush success! \n");
   2456         }
   2457     }
   2458 
   2459     // flush output port
   2460     if(output_flush_progress)
   2461     {
   2462 		buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2463 
   2464 		if(ioctl(drv_ctx.video_vpu_fd, VPU_FLUSH_BUFS, &buf_type))
   2465         {
   2466            DEBUG_PRINT_ERROR("VDPP output Flush error! \n");
   2467            return false;
   2468         }
   2469         else
   2470         {
   2471             DEBUG_PRINT_LOW("VDPP output Flush success! \n");
   2472         }
   2473     }
   2474 #endif
   2475 
   2476   return bRet;
   2477 }
   2478 /*=========================================================================
   2479 FUNCTION : execute_output_flush
   2480 
   2481 DESCRIPTION
   2482   Executes the OMX flush at OUTPUT PORT.
   2483 
   2484 PARAMETERS
   2485   None.
   2486 
   2487 RETURN VALUE
   2488   true/false
   2489 ==========================================================================*/
   2490 bool omx_vdpp::execute_output_flush()
   2491 {
   2492   unsigned      p1 = 0; // Parameter - 1
   2493   unsigned      p2 = 0; // Parameter - 2
   2494   unsigned      ident = 0;
   2495   bool bRet = true;
   2496 
   2497   /*Generate FBD for all Buffers in the FTBq*/
   2498   pthread_mutex_lock(&m_lock);
   2499   DEBUG_PRINT_LOW(" Initiate Output Flush, m_ftb_q.m_size = %d", m_ftb_q.m_size);
   2500   while (m_ftb_q.m_size)
   2501   {
   2502     DEBUG_PRINT_LOW(" Buffer queue size %d pending buf cnt %d",
   2503                        m_ftb_q.m_size,pending_output_buffers);
   2504     m_ftb_q.pop_entry(&p1,&p2,&ident);
   2505     DEBUG_PRINT_LOW(" ID(%x) P1(%x) P2(%x)", ident, p1, p2);
   2506     if(ident == m_fill_output_msg )
   2507     {
   2508       m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   2509     }
   2510     else if (ident == OMX_COMPONENT_GENERATE_FBD)
   2511     {
   2512       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   2513     }
   2514   }
   2515   pthread_mutex_unlock(&m_lock);
   2516   output_flush_progress = false;
   2517 
   2518   DEBUG_PRINT_HIGH(" OMX flush o/p Port complete PenBuf(%d), output_qbuf_count(%d), output_dqbuf_count(%d)",
   2519       pending_output_buffers, output_qbuf_count, output_dqbuf_count);
   2520   return bRet;
   2521 }
   2522 /*=========================================================================
   2523 FUNCTION : execute_input_flush
   2524 
   2525 DESCRIPTION
   2526   Executes the OMX flush at INPUT PORT.
   2527 
   2528 PARAMETERS
   2529   None.
   2530 
   2531 RETURN VALUE
   2532   true/false
   2533 ==========================================================================*/
   2534 bool omx_vdpp::execute_input_flush()
   2535 {
   2536   unsigned       i =0;
   2537   unsigned      p1 = 0; // Parameter - 1
   2538   unsigned      p2 = 0; // Parameter - 2
   2539   unsigned      ident = 0;
   2540   bool bRet = true;
   2541 
   2542   /*Generate EBD for all Buffers in the ETBq*/
   2543   DEBUG_PRINT_LOW(" Initiate Input Flush \n");
   2544 
   2545   pthread_mutex_lock(&m_lock);
   2546   DEBUG_PRINT_LOW(" Check if the Queue is empty \n");
   2547   while (m_etb_q.m_size)
   2548   {
   2549     DEBUG_PRINT_LOW(" m_etb_q.m_size = %d \n", m_etb_q.m_size);
   2550     m_etb_q.pop_entry(&p1,&p2,&ident);
   2551     DEBUG_PRINT_LOW("ident = %d \n", ident);
   2552     if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
   2553     {
   2554       DEBUG_PRINT_LOW(" Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   2555       m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   2556     }
   2557     else if(ident == OMX_COMPONENT_GENERATE_ETB)
   2558     {
   2559       pending_input_buffers++;
   2560       DEBUG_PRINT_LOW(" Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   2561         (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   2562       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   2563     }
   2564     else if (ident == OMX_COMPONENT_GENERATE_EBD)
   2565     {
   2566       DEBUG_PRINT_LOW(" Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   2567         (OMX_BUFFERHEADERTYPE *)p1);
   2568       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   2569     }
   2570   }
   2571 
   2572   pthread_mutex_unlock(&m_lock);
   2573   input_flush_progress = false;
   2574 
   2575   prev_ts = LLONG_MAX;
   2576   rst_prev_ts = true;
   2577 
   2578 #ifdef _ANDROID_
   2579   if (m_debug_timestamp)
   2580   {
   2581     m_timestamp_list.reset_ts_list();
   2582   }
   2583 #endif
   2584 
   2585   DEBUG_PRINT_HIGH(" OMX flush i/p Port complete PenBuf(%d), input_qbuf_count(%d), input_dqbuf_count(%d)",
   2586       pending_input_buffers, input_qbuf_count, input_dqbuf_count);
   2587   return bRet;
   2588 }
   2589 
   2590 
   2591 /* ======================================================================
   2592 FUNCTION
   2593   omx_vdpp::SendCommandEvent
   2594 
   2595 DESCRIPTION
   2596   Send the event to VDPP pipe.  This is needed to generate the callbacks
   2597   in VDPP thread context.
   2598 
   2599 PARAMETERS
   2600   None.
   2601 
   2602 RETURN VALUE
   2603   true/false
   2604 
   2605 ========================================================================== */
   2606 bool omx_vdpp::post_event(unsigned int p1,
   2607                           unsigned int p2,
   2608                           unsigned int id)
   2609 {
   2610   bool bRet = false;
   2611 
   2612   pthread_mutex_lock(&m_lock);
   2613   //DEBUG_PRINT_LOW("m_fill_output_msg = %d, OMX_COMPONENT_GENERATE_FBD = %d, id = %d", m_fill_output_msg, OMX_COMPONENT_GENERATE_FBD, id);
   2614   if (id == m_fill_output_msg ||
   2615       id == OMX_COMPONENT_GENERATE_FBD)
   2616   {
   2617     //DEBUG_PRINT_LOW(" post_event p2 = 0x%x, id = 0x%x", p2, id);
   2618     m_ftb_q.insert_entry(p1,p2,id);
   2619   }
   2620   else if (id == OMX_COMPONENT_GENERATE_ETB ||
   2621            id == OMX_COMPONENT_GENERATE_EBD ||
   2622            id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY)
   2623   {
   2624 	  m_etb_q.insert_entry(p1,p2,id);
   2625   }
   2626   else
   2627   {
   2628     m_cmd_q.insert_entry(p1,p2,id);
   2629   }
   2630 
   2631   bRet = true;
   2632   //DEBUG_PRINT_LOW(" Value of this pointer in post_event %p, id = %d",this, id);
   2633   post_message(this, id);
   2634 
   2635   pthread_mutex_unlock(&m_lock);
   2636 
   2637   return bRet;
   2638 }
   2639 
   2640 /* ======================================================================
   2641 FUNCTION
   2642   omx_vdpp::GetParameter
   2643 
   2644 DESCRIPTION
   2645   OMX Get Parameter method implementation
   2646 
   2647 PARAMETERS
   2648   <TBD>.
   2649 
   2650 RETURN VALUE
   2651   Error None if successful.
   2652 
   2653 ========================================================================== */
   2654 OMX_ERRORTYPE  omx_vdpp::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2655                                            OMX_IN OMX_INDEXTYPE paramIndex,
   2656                                            OMX_INOUT OMX_PTR     paramData)
   2657 {
   2658     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2659 
   2660     DEBUG_PRINT_HIGH("get_parameter: \n");
   2661     if(m_state == OMX_StateInvalid)
   2662     {
   2663         DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
   2664         return OMX_ErrorInvalidState;
   2665     }
   2666     if(paramData == NULL)
   2667     {
   2668         DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
   2669         return OMX_ErrorBadParameter;
   2670     }
   2671   //DEBUG_PRINT_HIGH("get_parameter 1 : \n");
   2672   switch((unsigned long)paramIndex)
   2673   {
   2674     case OMX_IndexParamPortDefinition:
   2675     {
   2676       OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   2677                             (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2678       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
   2679       eRet = update_portdef(portDefn);
   2680       if (eRet == OMX_ErrorNone)
   2681           m_port_def = *portDefn;
   2682       break;
   2683     }
   2684     case OMX_IndexParamVideoInit:
   2685     {
   2686       OMX_PORT_PARAM_TYPE *portParamType =
   2687                               (OMX_PORT_PARAM_TYPE *) paramData;
   2688       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
   2689 
   2690       portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2691       portParamType->nSize = sizeof(portParamType);
   2692       portParamType->nPorts           = 2;
   2693       portParamType->nStartPortNumber = 0;
   2694       break;
   2695     }
   2696     case OMX_IndexParamVideoPortFormat:
   2697     {
   2698       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2699                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   2700       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
   2701 
   2702       portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   2703       portFmt->nSize             = sizeof(portFmt);
   2704 
   2705       if (OMX_CORE_INPUT_PORT_INDEX == portFmt->nPortIndex)
   2706       {
   2707         if (0 == portFmt->nIndex)
   2708         {
   2709               portFmt->eColorFormat =  (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;//OMX_COLOR_FormatYUV420Planar;//OMX_COLOR_FormatUnused;
   2710               portFmt->eCompressionFormat = OMX_VIDEO_CodingUnused;
   2711         }
   2712         else
   2713         {
   2714           DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2715               " NoMore compression formats\n");
   2716           eRet =  OMX_ErrorNoMore;
   2717         }
   2718       }
   2719       else if (OMX_CORE_OUTPUT_PORT_INDEX == portFmt->nPortIndex)
   2720       {
   2721         portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   2722 
   2723         if(0 == portFmt->nIndex)
   2724             portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
   2725                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2726         else
   2727         {
   2728            DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2729                   " NoMore Color formats\n");
   2730            eRet =  OMX_ErrorNoMore;
   2731         }
   2732 	    DEBUG_PRINT_ERROR("returning %d\n", portFmt->eColorFormat);
   2733       }
   2734       else
   2735       {
   2736         DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
   2737                           (int)portFmt->nPortIndex);
   2738         eRet = OMX_ErrorBadPortIndex;
   2739       }
   2740       break;
   2741     }
   2742     /*Component should support this port definition*/
   2743     case OMX_IndexParamAudioInit:
   2744     {
   2745         OMX_PORT_PARAM_TYPE *audioPortParamType =
   2746                                               (OMX_PORT_PARAM_TYPE *) paramData;
   2747         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
   2748         audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2749         audioPortParamType->nSize = sizeof(audioPortParamType);
   2750         audioPortParamType->nPorts           = 0;
   2751         audioPortParamType->nStartPortNumber = 0;
   2752         break;
   2753     }
   2754     /*Component should support this port definition*/
   2755     case OMX_IndexParamImageInit:
   2756     {
   2757         OMX_PORT_PARAM_TYPE *imagePortParamType =
   2758                                               (OMX_PORT_PARAM_TYPE *) paramData;
   2759         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
   2760         imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2761         imagePortParamType->nSize = sizeof(imagePortParamType);
   2762         imagePortParamType->nPorts           = 0;
   2763         imagePortParamType->nStartPortNumber = 0;
   2764         break;
   2765 
   2766     }
   2767     /*Component should support this port definition*/
   2768     case OMX_IndexParamOtherInit:
   2769     {
   2770         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
   2771                           paramIndex);
   2772         eRet =OMX_ErrorUnsupportedIndex;
   2773         break;
   2774     }
   2775     case OMX_IndexParamStandardComponentRole:
   2776     {
   2777         OMX_PARAM_COMPONENTROLETYPE *comp_role;
   2778         comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   2779         comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   2780         comp_role->nSize = sizeof(*comp_role);
   2781 
   2782         DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
   2783                     paramIndex);
   2784         strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   2785                     OMX_MAX_STRINGNAME_SIZE);
   2786         break;
   2787     }
   2788     /* Added for parameter test */
   2789     case OMX_IndexParamPriorityMgmt:
   2790         {
   2791 
   2792             OMX_PRIORITYMGMTTYPE *priorityMgmType =
   2793                                              (OMX_PRIORITYMGMTTYPE *) paramData;
   2794             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
   2795             priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   2796             priorityMgmType->nSize = sizeof(priorityMgmType);
   2797 
   2798             break;
   2799         }
   2800     /* Added for parameter test */
   2801     case OMX_IndexParamCompBufferSupplier:
   2802         {
   2803             OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   2804                                      (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   2805             DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
   2806 
   2807             bufferSupplierType->nSize = sizeof(bufferSupplierType);
   2808             bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   2809             if(OMX_CORE_INPUT_PORT_INDEX == bufferSupplierType->nPortIndex)
   2810                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2811             else if (OMX_CORE_OUTPUT_PORT_INDEX == bufferSupplierType->nPortIndex)
   2812                 bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2813             else
   2814                 eRet = OMX_ErrorBadPortIndex;
   2815 
   2816 
   2817             break;
   2818         }
   2819 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   2820     case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
   2821         {
   2822             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   2823             GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   2824             if((nativeBuffersUsage->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) || (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX))
   2825             {
   2826 #ifdef USE_ION
   2827 #if defined (MAX_RES_720P)
   2828                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_CAMERA_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
   2829                 DEBUG_PRINT_HIGH("ION:720P: nUsage 0x%x",nativeBuffersUsage->nUsage);
   2830 #else
   2831                 {
   2832                     nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_MM_HEAP;
   2833                     DEBUG_PRINT_HIGH("ION:non_secure_mode: nUsage 0x%lx",nativeBuffersUsage->nUsage);
   2834                 }
   2835 #endif //(MAX_RES_720P)
   2836 #else // USE_ION
   2837 #if defined (MAX_RES_720P) ||  defined (MAX_RES_1080P_EBI)
   2838                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
   2839                 DEBUG_PRINT_HIGH("720P/1080P_EBI: nUsage 0x%x",nativeBuffersUsage->nUsage);
   2840 #elif MAX_RES_1080P
   2841                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_SMI_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
   2842                 DEBUG_PRINT_HIGH("1080P: nUsage 0x%x",nativeBuffersUsage->nUsage);
   2843 #endif
   2844 #endif // USE_ION
   2845             } else {
   2846                 DEBUG_PRINT_ERROR(" get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   2847                 eRet = OMX_ErrorBadParameter;
   2848             }
   2849         }
   2850         break;
   2851 #endif
   2852 
   2853     default:
   2854     {
   2855       DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
   2856       eRet =OMX_ErrorUnsupportedIndex;
   2857     }
   2858 
   2859   }
   2860 
   2861   DEBUG_PRINT_LOW(" get_parameter returning input WxH(%d x %d) SxSH(%d x %d)\n",
   2862       drv_ctx.video_resolution_input.frame_width,
   2863       drv_ctx.video_resolution_input.frame_height,
   2864       drv_ctx.video_resolution_input.stride,
   2865       drv_ctx.video_resolution_input.scan_lines);
   2866 
   2867   DEBUG_PRINT_LOW(" get_parameter returning output WxH(%d x %d) SxSH(%d x %d)\n",
   2868       drv_ctx.video_resolution_output.frame_width,
   2869       drv_ctx.video_resolution_output.frame_height,
   2870       drv_ctx.video_resolution_output.stride,
   2871       drv_ctx.video_resolution_output.scan_lines);
   2872 
   2873   return eRet;
   2874 }
   2875 
   2876 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   2877 OMX_ERRORTYPE omx_vdpp::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   2878 {
   2879     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   2880     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2881     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   2882 
   2883     if((params == NULL) ||
   2884       (params->nativeBuffer == NULL) ||
   2885       (params->nativeBuffer->handle == NULL) ||
   2886       !m_enable_android_native_buffers)
   2887         return OMX_ErrorBadParameter;
   2888     m_use_android_native_buffers = OMX_TRUE;
   2889     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   2890     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   2891     if(OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) {  //android native buffers can be used only on Output port
   2892         OMX_U8 *buffer = NULL;
   2893 
   2894         buffer = (OMX_U8*)mmap(0, handle->size,
   2895             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   2896         if(buffer == MAP_FAILED) {
   2897             DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   2898             return OMX_ErrorInsufficientResources;
   2899     }
   2900         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   2901     } else {
   2902         eRet = OMX_ErrorBadParameter;
   2903     }
   2904     return eRet;
   2905 }
   2906 #endif
   2907 /* ======================================================================
   2908 FUNCTION
   2909   omx_vdpp::Setparameter
   2910 
   2911 DESCRIPTION
   2912   OMX Set Parameter method implementation.
   2913 
   2914 PARAMETERS
   2915   <TBD>.
   2916 
   2917 RETURN VALUE
   2918   OMX Error None if successful.
   2919 
   2920 ========================================================================== */
   2921 OMX_ERRORTYPE  omx_vdpp::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2922                                            OMX_IN OMX_INDEXTYPE paramIndex,
   2923                                            OMX_IN OMX_PTR        paramData)
   2924 {
   2925     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2926     int ret=0;
   2927     int i = 0;
   2928     struct v4l2_format fmt;
   2929 
   2930     if(m_state == OMX_StateInvalid)
   2931     {
   2932         DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
   2933         return OMX_ErrorInvalidState;
   2934     }
   2935     if(paramData == NULL)
   2936     {
   2937          DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
   2938          return OMX_ErrorBadParameter;
   2939     }
   2940     if((m_state != OMX_StateLoaded) &&
   2941           BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   2942           (m_out_bEnabled == OMX_TRUE) &&
   2943           BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   2944           (m_inp_bEnabled == OMX_TRUE)) {
   2945         DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
   2946         return OMX_ErrorIncorrectStateOperation;
   2947     }
   2948   switch((unsigned long)paramIndex)
   2949   {
   2950     case OMX_IndexParamPortDefinition:
   2951     {
   2952       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   2953       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2954 
   2955       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
   2956              (int)portDefn->format.video.nFrameHeight,
   2957              (int)portDefn->format.video.nFrameWidth);
   2958 
   2959       if(OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
   2960       {
   2961           DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
   2962 
   2963           unsigned int buffer_size;
   2964           memset(&fmt, 0, sizeof(fmt));
   2965 
   2966           // set output resolution based on port definition. scan_lines and stride settings need
   2967           //  to match format setting requirement (QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m)
   2968           {
   2969              DEBUG_PRINT_LOW(" SetParam OP: WxH(%lu x %lu)\n",
   2970                            portDefn->format.video.nFrameWidth,
   2971                            portDefn->format.video.nFrameHeight);
   2972              if (portDefn->format.video.nFrameHeight != 0x0 &&
   2973                  portDefn->format.video.nFrameWidth != 0x0)
   2974              {
   2975                 drv_ctx.video_resolution_output.frame_height = portDefn->format.video.nFrameHeight;
   2976                 drv_ctx.video_resolution_output.frame_width = portDefn->format.video.nFrameWidth;
   2977                 drv_ctx.video_resolution_output.scan_lines = paddedFrameWidth32(portDefn->format.video.nFrameHeight);
   2978                 drv_ctx.video_resolution_output.stride = paddedFrameWidth128(portDefn->format.video.nFrameWidth);
   2979 
   2980 		        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2981 		        fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
   2982 		        fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
   2983 		        fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   2984 		        fmt.fmt.pix_mp.pixelformat = capture_capability;
   2985                 DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d, drv_ctx.video_resolution_output.stride = %d, drv_ctx.video_resolution_output.scan_lines = %d", fmt.fmt.pix_mp.width,
   2986                         fmt.fmt.pix_mp.height, drv_ctx.video_resolution_output.stride, drv_ctx.video_resolution_output.scan_lines);
   2987                 // NV12 has 2 planes.
   2988                 /* Set format for each plane. */
   2989                 setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   2990                 for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   2991                 {
   2992                     fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[i] * fmt.fmt.pix_mp.height);
   2993                     fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]); // both plane have the same plane stride
   2994 			    DEBUG_PRINT_HIGH("before VIDIOC_S_FMT (op) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   2995 
   2996                 }
   2997 
   2998 #ifndef STUB_VPU
   2999                 ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   3000                 for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3001                 {
   3002 			    DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (op) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   3003                 }
   3004 
   3005                 if (ret)
   3006                 {
   3007                     DEBUG_PRINT_ERROR(" Set Resolution failed");
   3008                     eRet = OMX_ErrorUnsupportedSetting;
   3009                 }
   3010                 else
   3011 #endif
   3012                 {
   3013                     eRet = get_buffer_req(&drv_ctx.op_buf);
   3014 
   3015                    // eRet = get_buffer_req(&drv_ctx.ip_buf);
   3016                 }
   3017 
   3018               }
   3019            }
   3020            if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount /*||
   3021                     portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size*/ )
   3022            {
   3023                 drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
   3024                 //drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
   3025                 eRet = set_buffer_req(&drv_ctx.op_buf);
   3026                 if (eRet == OMX_ErrorNone)
   3027                     m_port_def = *portDefn;
   3028            }
   3029            else
   3030            {
   3031                 DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
   3032                         drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
   3033                         portDefn->nBufferCountActual, portDefn->nBufferSize);
   3034                 eRet = OMX_ErrorBadParameter;
   3035            }
   3036       }
   3037       else if(OMX_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex)
   3038       {
   3039         // TODO for 8092 the frame rate code below can be enabled to debug frame rate
   3040 #ifdef FRC_ENABLE
   3041         if((portDefn->format.video.xFramerate >> 16) > 0 &&
   3042            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS)
   3043         {
   3044             // Frame rate only should be set if this is a "known value" or to
   3045             // activate ts prediction logic (arbitrary mode only) sending input
   3046             // timestamps with max value (LLONG_MAX).
   3047             DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
   3048                              portDefn->format.video.xFramerate >> 16);
   3049             Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   3050                           drv_ctx.frame_rate.fps_denominator);
   3051             if(!drv_ctx.frame_rate.fps_numerator)
   3052             {
   3053               DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   3054               drv_ctx.frame_rate.fps_numerator = 30;
   3055             }
   3056             if(drv_ctx.frame_rate.fps_denominator)
   3057               drv_ctx.frame_rate.fps_numerator = (int)
   3058                   drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   3059               drv_ctx.frame_rate.fps_denominator = 1;
   3060             frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   3061                       drv_ctx.frame_rate.fps_numerator;
   3062             DEBUG_PRINT_HIGH("set_parameter: frm_int(%lu) fps(%.2f)",
   3063                              frm_int, drv_ctx.frame_rate.fps_numerator /
   3064                              (float)drv_ctx.frame_rate.fps_denominator);
   3065 
   3066             struct v4l2_outputparm oparm;
   3067             /*XXX: we're providing timing info as seconds per frame rather than frames
   3068                 * per second.*/
   3069             oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   3070             oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   3071 
   3072             struct v4l2_streamparm sparm;
   3073             memset(&sparm, 0, sizeof(struct v4l2_streamparm));
   3074             sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3075             sparm.parm.output = oparm;
   3076             if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_PARM, &sparm)) {
   3077                 DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   3078                         performance might be affected");
   3079                 eRet = OMX_ErrorHardware;
   3080             }
   3081         }
   3082 #endif
   3083          memset(&fmt, 0, sizeof(fmt));
   3084          DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
   3085          if(drv_ctx.video_resolution_input.frame_height !=
   3086                portDefn->format.video.nFrameHeight ||
   3087              drv_ctx.video_resolution_input.frame_width  !=
   3088                portDefn->format.video.nFrameWidth)
   3089          {
   3090              DEBUG_PRINT_LOW(" SetParam IP: WxH(%lu x %lu)\n",
   3091                            portDefn->format.video.nFrameWidth,
   3092                            portDefn->format.video.nFrameHeight);
   3093              if (portDefn->format.video.nFrameHeight != 0x0 &&
   3094                  portDefn->format.video.nFrameWidth != 0x0)
   3095              {
   3096                  update_resolution(portDefn->format.video.nFrameWidth,
   3097                     (portDefn->format.video.nFrameHeight),
   3098 					portDefn->format.video.nStride,
   3099 					(portDefn->format.video.nSliceHeight));
   3100 
   3101                 // decoder stride information is not used in S_FMT and QBUF, since paddedWidth
   3102                 // will ensure the buffer length/size is always aligned with 128 bytes, which
   3103                 // has the same effect as stride.
   3104                 // output has Width 720, and nStride = 768
   3105 		        fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3106 		        fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
   3107 		        fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
   3108                 if (V4L2_FIELD_NONE == drv_ctx.interlace)
   3109                 {
   3110 		        fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   3111                 }
   3112                 else
   3113                 {
   3114 		        fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
   3115                 }
   3116 		        fmt.fmt.pix_mp.pixelformat = output_capability;
   3117 
   3118                 // NV12 has 2 planes.
   3119                 /* Set format for each plane. */
   3120                 setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   3121                 for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3122                 {
   3123                     fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[i] * fmt.fmt.pix_mp.height);
   3124                     fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // both plane have the same plane stride
   3125 			    DEBUG_PRINT_HIGH("before VIDIOC_S_FMT (ip) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   3126                 }
   3127 
   3128 #ifndef STUB_VPU
   3129                 ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   3130               //  for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3131               //  {
   3132 			    //DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (ip) fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   3133               //  }
   3134                 if (ret)
   3135                 {
   3136                     DEBUG_PRINT_ERROR(" Set Resolution failed");
   3137                     eRet = OMX_ErrorUnsupportedSetting;
   3138                 }
   3139                 else
   3140 #endif
   3141                 {
   3142                     DEBUG_PRINT_HIGH("after VIDIOC_S_FMT (ip) drv_ctx.interlace = %d", drv_ctx.interlace);
   3143                     // set output resolution the same as input
   3144                     drv_ctx.video_resolution_output.frame_height = portDefn->format.video.nFrameHeight;
   3145                     drv_ctx.video_resolution_output.frame_width = portDefn->format.video.nFrameWidth;
   3146                     drv_ctx.video_resolution_output.scan_lines = paddedFrameWidth32(portDefn->format.video.nSliceHeight);
   3147                     drv_ctx.video_resolution_output.stride = paddedFrameWidth128(portDefn->format.video.nStride);
   3148 
   3149 		            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3150 		            fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
   3151 		            fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
   3152 		            fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   3153 		            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3154                     DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d, drv_ctx.video_resolution_output.stride = %d, drv_ctx.video_resolution_output.scan_lines = %d", fmt.fmt.pix_mp.width,
   3155                             fmt.fmt.pix_mp.height, drv_ctx.video_resolution_output.stride, drv_ctx.video_resolution_output.scan_lines);
   3156                     // NV12 has 2 planes.
   3157                     /* Set format for each plane. */
   3158                     setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   3159                     for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3160                     {
   3161                         fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[i] * fmt.fmt.pix_mp.height);
   3162                         fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]); // both plane have the same plane stride
   3163 				    DEBUG_PRINT_HIGH("before VIDIOC_S_FMT op fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   3164                     }
   3165 
   3166     #ifndef STUB_VPU
   3167                     ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   3168                     for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3169                     {
   3170 				    DEBUG_PRINT_HIGH("after VIDIOC_S_FMT op fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n",i,fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   3171                     }
   3172 
   3173                     if (ret)
   3174                     {
   3175                         DEBUG_PRINT_ERROR(" Set Resolution failed");
   3176                         eRet = OMX_ErrorUnsupportedSetting;
   3177                     }
   3178                     else
   3179     #endif
   3180                     {
   3181                         // get buffer req for input, output buffer size is
   3182                         // determined by output pixel format and output resolution
   3183                         //eRet = get_buffer_req(&drv_ctx.op_buf);
   3184                         eRet = get_buffer_req(&drv_ctx.ip_buf);
   3185                     }
   3186                 }
   3187              }
   3188          }
   3189 
   3190          if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   3191              /*|| portDefn->nBufferSize >= drv_ctx.ip_buf.buffer_size*/)
   3192              // only allocate larger size
   3193          {
   3194              DEBUG_PRINT_HIGH("portDefn->nBufferCountActual = %lu portDefn->nBufferSize = %lu, drv_ctx.ip_buf.buffer_size=%d \n", portDefn->nBufferCountActual, portDefn->nBufferSize, drv_ctx.ip_buf.buffer_size);
   3195              vdpp_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   3196              drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   3197              //if(portDefn->nBufferSize >= drv_ctx.ip_buf.buffer_size)
   3198              //{
   3199              //    drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   3200              //             (~(buffer_prop->alignment - 1));
   3201              //    DEBUG_PRINT_HIGH("drv_ctx.ip_buf.buffer_size = %d, buffer_prop->alignment = %d\n", drv_ctx.ip_buf.buffer_size, buffer_prop->alignment);
   3202              //}
   3203              eRet = set_buffer_req(buffer_prop);
   3204          }
   3205          else
   3206          {
   3207              DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
   3208                drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
   3209                portDefn->nBufferCountActual, portDefn->nBufferSize);
   3210              eRet = OMX_ErrorBadParameter;
   3211          }
   3212       }
   3213       else if (portDefn->eDir ==  OMX_DirMax)
   3214       {
   3215           DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   3216                       (int)portDefn->nPortIndex);
   3217           eRet = OMX_ErrorBadPortIndex;
   3218       }
   3219     }
   3220     break;
   3221     case OMX_IndexParamVideoPortFormat:
   3222     {
   3223       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3224                      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3225       int ret=0;
   3226       struct v4l2_format fmt;
   3227       DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
   3228               portFmt->eColorFormat);
   3229 
   3230       if(OMX_CORE_OUTPUT_PORT_INDEX == portFmt->nPortIndex)
   3231       {
   3232             uint32_t op_format;
   3233 
   3234             memset(&fmt, 0, sizeof(fmt));
   3235             fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3236             fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
   3237             fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
   3238             fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   3239 
   3240           // TODO based on output format
   3241           // update OMX format type for additional output format supported by 8084
   3242           if((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   3243                       QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
   3244               (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
   3245               op_format = (uint32_t)V4L2_PIX_FMT_NV12;
   3246           else if(portFmt->eColorFormat ==
   3247                   (OMX_COLOR_FORMATTYPE)
   3248                   QOMX_COLOR_FormatYVU420SemiPlanar)
   3249               op_format = V4L2_PIX_FMT_NV21;
   3250           else
   3251               eRet = OMX_ErrorBadParameter;
   3252 
   3253           if(eRet == OMX_ErrorNone)
   3254           {
   3255               drv_ctx.output_format = op_format;
   3256               capture_capability = op_format;
   3257               fmt.fmt.pix_mp.pixelformat = capture_capability;
   3258 
   3259               DEBUG_PRINT_HIGH("VP output frame width = %d, height = %d", fmt.fmt.pix_mp.width,
   3260                     fmt.fmt.pix_mp.height);
   3261 
   3262               setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   3263               for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   3264               {
   3265                   fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
   3266                                                                            drv_ctx.output_bytesperpixel[i]  *
   3267                                                                            fmt.fmt.pix_mp.height);
   3268                   fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
   3269               }
   3270 #ifndef STUB_VPU
   3271               ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   3272               if(ret)
   3273               {
   3274                   DEBUG_PRINT_ERROR(" Set output format failed");
   3275                   eRet = OMX_ErrorUnsupportedSetting;
   3276               }
   3277               else
   3278 #endif
   3279               {
   3280                   eRet = get_buffer_req(&drv_ctx.op_buf);
   3281               }
   3282           }
   3283       }
   3284     }
   3285     break;
   3286 
   3287      case OMX_IndexParamStandardComponentRole:
   3288      {
   3289           OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3290           comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3291           DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
   3292                        comp_role->cRole);
   3293 
   3294           if((m_state == OMX_StateLoaded)&&
   3295               !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3296           {
   3297            DEBUG_PRINT_LOW("Set Parameter called in valid state");
   3298           }
   3299           else
   3300           {
   3301              DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   3302              return OMX_ErrorIncorrectStateOperation;
   3303           }
   3304 
   3305           // no component role yet
   3306        /*   if(!strncmp(drv_ctx.kind, "OMX.qcom.video.vidpp",OMX_MAX_STRINGNAME_SIZE))
   3307           {
   3308               if(!strncmp((char*)comp_role->cRole,"video.vidpp",OMX_MAX_STRINGNAME_SIZE))
   3309               {
   3310                   strlcpy((char*)m_cRole,"video.vidpp",OMX_MAX_STRINGNAME_SIZE);
   3311               }
   3312               else
   3313               {
   3314                   DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3315                   eRet =OMX_ErrorUnsupportedSetting;
   3316               }
   3317           }
   3318           else
   3319           {
   3320                DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
   3321                eRet = OMX_ErrorInvalidComponentName;
   3322           } */
   3323           break;
   3324      }
   3325 
   3326     case OMX_IndexParamPriorityMgmt:
   3327         {
   3328             if(m_state != OMX_StateLoaded)
   3329             {
   3330                DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   3331                return OMX_ErrorIncorrectStateOperation;
   3332             }
   3333             OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   3334             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
   3335               priorityMgmtype->nGroupID);
   3336 
   3337             DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
   3338              priorityMgmtype->nGroupPriority);
   3339 
   3340             m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   3341             m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   3342 
   3343             break;
   3344         }
   3345 
   3346       case OMX_IndexParamCompBufferSupplier:
   3347       {
   3348           OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3349             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
   3350                 bufferSupplierType->eBufferSupplier);
   3351              if(bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   3352                 m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   3353 
   3354              else
   3355 
   3356              eRet = OMX_ErrorBadPortIndex;
   3357 
   3358           break;
   3359 
   3360       }
   3361 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3362       /* Need to allow following two set_parameters even in Idle
   3363        * state. This is ANDROID architecture which is not in sync
   3364        * with openmax standard. */
   3365     case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
   3366       {
   3367           EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   3368           if(enableNativeBuffers) {
   3369               m_enable_android_native_buffers = enableNativeBuffers->enable;
   3370           }
   3371           DEBUG_PRINT_HIGH("OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: enableNativeBuffers %d\n", m_enable_android_native_buffers);
   3372       }
   3373       break;
   3374     case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
   3375       {
   3376           eRet = use_android_native_buffer(hComp, paramData);
   3377       }
   3378       break;
   3379 #endif
   3380     case OMX_QcomIndexParamInterlaceExtraData:
   3381           eRet = enable_extradata(OMX_INTERLACE_EXTRADATA,
   3382                               ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3383 
   3384       break;
   3385     case OMX_IndexParamInterlaceFormat:
   3386         {
   3387             OMX_INTERLACEFORMATTYPE *interlaceFormat = ( OMX_INTERLACEFORMATTYPE *)paramData;
   3388             DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamInterlaceFormat %ld\n",
   3389                 interlaceFormat->nFormat);
   3390 
   3391             if(OMX_InterlaceInterleaveFrameBottomFieldFirst == (OMX_U32)interlaceFormat->nFormat)
   3392             {
   3393                 drv_ctx.interlace = V4L2_FIELD_INTERLACED_BT;
   3394                 DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_INTERLACED_BT");
   3395                 interlace_user_flag = true;
   3396             }
   3397             else if(OMX_InterlaceInterleaveFrameTopFieldFirst == (OMX_U32)interlaceFormat->nFormat)
   3398             {
   3399                 drv_ctx.interlace = V4L2_FIELD_INTERLACED_TB;
   3400                 DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_INTERLACED_TB");
   3401                 interlace_user_flag = true;
   3402             }
   3403             else if(OMX_InterlaceFrameProgressive == (OMX_U32)interlaceFormat->nFormat)
   3404             {
   3405                 drv_ctx.interlace = V4L2_FIELD_NONE;
   3406                 DEBUG_PRINT_LOW("set_parameter: V4L2_FIELD_NONE");
   3407                 interlace_user_flag = true;
   3408             }
   3409             else
   3410             {
   3411                 DEBUG_PRINT_ERROR("Setparameter: unknown param %lu\n", interlaceFormat->nFormat);
   3412                 eRet = OMX_ErrorBadParameter;
   3413             }
   3414         }
   3415       break;
   3416     default:
   3417     {
   3418       DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
   3419       eRet = OMX_ErrorUnsupportedIndex;
   3420     }
   3421   }
   3422   return eRet;
   3423 }
   3424 
   3425 /* ======================================================================
   3426 FUNCTION
   3427   omx_vdpp::GetConfig
   3428 
   3429 DESCRIPTION
   3430   OMX Get Config Method implementation.
   3431 
   3432 PARAMETERS
   3433   <TBD>.
   3434 
   3435 RETURN VALUE
   3436   OMX Error None if successful.
   3437 
   3438 ========================================================================== */
   3439 OMX_ERRORTYPE  omx_vdpp::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   3440                                         OMX_IN OMX_INDEXTYPE configIndex,
   3441                                         OMX_INOUT OMX_PTR     configData)
   3442 {
   3443   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3444 
   3445   if (m_state == OMX_StateInvalid)
   3446   {
   3447      DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   3448      return OMX_ErrorInvalidState;
   3449   }
   3450 
   3451   switch ((unsigned long)configIndex)
   3452   {
   3453 	case OMX_IndexConfigCommonOutputCrop:
   3454     {
   3455       OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   3456       memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   3457       break;
   3458     }
   3459 
   3460     // OMX extensions
   3461       case OMX_QcomIndexConfigActiveRegionDetectionStatus:
   3462           break;
   3463 
   3464     default:
   3465     {
   3466       DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
   3467       eRet = OMX_ErrorBadParameter;
   3468     }
   3469 
   3470   }
   3471 
   3472   return eRet;
   3473 }
   3474 
   3475 /* ======================================================================
   3476 FUNCTION
   3477   omx_vdpp::SetConfig
   3478 
   3479 DESCRIPTION
   3480   OMX Set Config method implementation
   3481 
   3482 PARAMETERS
   3483   <TBD>.
   3484 
   3485 RETURN VALUE
   3486   OMX Error None if successful.
   3487 ========================================================================== */
   3488 OMX_ERRORTYPE  omx_vdpp::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   3489                                         OMX_IN OMX_INDEXTYPE configIndex,
   3490                                         OMX_IN OMX_PTR        configData)
   3491 {
   3492   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3493   struct vpu_control control;
   3494   int result = 0;
   3495 
   3496   DEBUG_PRINT_LOW("omx_vdpp::set_config \n");
   3497   if(m_state == OMX_StateInvalid)
   3498   {
   3499       DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   3500       return OMX_ErrorInvalidState;
   3501   }
   3502 
   3503   switch ((unsigned long)configIndex)
   3504   {
   3505       // OMX extensions
   3506       case OMX_QcomIndexConfigActiveRegionDetection:
   3507       {
   3508           struct vpu_ctrl_active_region_param *ard = &control.data.active_region_param;
   3509           memset(&control, 0, sizeof(control));
   3510           control.control_id = VPU_CTRL_ACTIVE_REGION_PARAM;
   3511           mExtensionData.activeRegionDetectionDirtyFlag = true;
   3512           memcpy(&(mExtensionData.activeRegionDetection),
   3513                  configData,
   3514                  sizeof(mExtensionData.activeRegionDetection));
   3515 
   3516           /* Set control. */
   3517 	  ard->enable = mExtensionData.activeRegionDetection.bEnable;
   3518 	  ard->num_exclusions = mExtensionData.activeRegionDetection.nNumExclusionRegions;
   3519           memcpy(&(ard->detection_region), &(mExtensionData.activeRegionDetection.sROI), sizeof(QOMX_RECTTYPE));
   3520           if(ard->num_exclusions > 0)
   3521           {
   3522             memcpy(&(ard->detection_region), &(mExtensionData.activeRegionDetection.sExclusionRegions), (ard->num_exclusions * sizeof(QOMX_RECTTYPE)));
   3523           }
   3524 
   3525 	  DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ACTIVE_REGION_MEASURE : "
   3526 				        "top %d left %d width %d height %d",
   3527 				        ard->detection_region.top, ard->detection_region.left,
   3528 				        ard->detection_region.width, ard->detection_region.height);
   3529 #ifndef STUB_VPU
   3530           result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
   3531           if (result < 0)
   3532           {
   3533               DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_ACTIVE_REGION_MEASURE failed, result = %d", result);
   3534               eRet = OMX_ErrorUnsupportedSetting;
   3535           }
   3536           else
   3537           {
   3538               mExtensionData.activeRegionDetectionDirtyFlag = false;
   3539 		  DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ACTIVE_REGION_MEASURE set to: "
   3540 				            "top %d left %d width %d height %d",
   3541 				            ard->detection_region.top, ard->detection_region.left,
   3542 				            ard->detection_region.width, ard->detection_region.height);
   3543           }
   3544 #endif
   3545           break;
   3546       }
   3547 
   3548       case OMX_QcomIndexConfigScalingMode:
   3549         {
   3550           struct vpu_ctrl_standard *anmph = &control.data.standard;
   3551           memset(&control, 0, sizeof(control));
   3552           control.control_id = VPU_CTRL_ANAMORPHIC_SCALING;
   3553           mExtensionData.scalingModeDirtyFlag = true;
   3554           memcpy(&(mExtensionData.scalingMode),
   3555                  configData,
   3556                  sizeof(mExtensionData.scalingMode));
   3557 
   3558           /* Set control. */
   3559 	  anmph->enable = 1;
   3560 	  anmph->value = mExtensionData.scalingMode.eScaleMode;
   3561 
   3562           DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ANAMORPHIC_SCALING %d, anmph->enable = %d", anmph->value, anmph->enable);
   3563 #ifndef STUB_VPU
   3564           result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
   3565           if (result < 0)
   3566           {
   3567               DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_ANAMORPHIC_SCALING failed, result = %d", result);
   3568               eRet = OMX_ErrorUnsupportedSetting;
   3569           }
   3570           else
   3571           {
   3572               mExtensionData.scalingModeDirtyFlag = false;
   3573               DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_ANAMORPHIC_SCALING set to %d", anmph->value);
   3574           }
   3575 #endif
   3576           break;
   3577         }
   3578 
   3579       case OMX_QcomIndexConfigNoiseReduction:
   3580         {
   3581           struct vpu_ctrl_auto_manual *nr = &control.data.auto_manual;
   3582           memset(&control, 0, sizeof(control));
   3583           control.control_id = VPU_CTRL_NOISE_REDUCTION;
   3584           mExtensionData.noiseReductionDirtyFlag = true;
   3585           memcpy(&(mExtensionData.noiseReduction),
   3586                  configData,
   3587                  sizeof(mExtensionData.noiseReduction));
   3588 
   3589           /* Set control. */
   3590 	  nr->enable = mExtensionData.noiseReduction.bEnable;
   3591 	  nr->auto_mode = mExtensionData.noiseReduction.bAutoMode;
   3592 	  nr->value = mExtensionData.noiseReduction.nNoiseReduction;
   3593 
   3594           DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_NOISE_REDUCTION %d, nr->enable = %d, nr->auto_mode = %d", nr->value, nr->enable, nr->auto_mode);
   3595 #ifndef STUB_VPU
   3596           result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
   3597           if (result < 0)
   3598           {
   3599               DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_NOISE_REDUCTION failed, result = %d", result);
   3600               eRet = OMX_ErrorUnsupportedSetting;
   3601           }
   3602           else
   3603           {
   3604               mExtensionData.noiseReductionDirtyFlag = false;
   3605               DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_NOISE_REDUCTION set to %d", nr->value);
   3606           }
   3607 #endif
   3608           break;
   3609         }
   3610 
   3611       case OMX_QcomIndexConfigImageEnhancement:
   3612         {
   3613           struct vpu_ctrl_auto_manual *ie = &control.data.auto_manual;
   3614           memset(&control, 0, sizeof(control));
   3615           control.control_id = VPU_CTRL_IMAGE_ENHANCEMENT;
   3616           mExtensionData.imageEnhancementDirtyFlag = true;
   3617           memcpy(&(mExtensionData.imageEnhancement),
   3618                  configData,
   3619                  sizeof(mExtensionData.imageEnhancement));
   3620 
   3621           /* Set control. */
   3622 	  ie->enable = mExtensionData.imageEnhancement.bEnable;
   3623 	  ie->auto_mode = mExtensionData.imageEnhancement.bAutoMode;
   3624 	  ie->value = mExtensionData.imageEnhancement.nImageEnhancement;
   3625 
   3626           DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_IMAGE_ENHANCEMENT %d, ie->enable = %d, ie->auto_mode = %d", ie->value, ie->enable, ie->auto_mode);
   3627 #ifndef STUB_VPU
   3628           result = ioctl(drv_ctx.video_vpu_fd, VPU_S_CONTROL, &control);
   3629           if (result < 0)
   3630           {
   3631               DEBUG_PRINT_ERROR("VIDIOC_S_CTRL VPU_S_CTRL_IMAGE_ENHANCEMENT failed, result = %d", result);
   3632               eRet = OMX_ErrorUnsupportedSetting;
   3633           }
   3634           else
   3635           {
   3636               mExtensionData.imageEnhancementDirtyFlag = false;
   3637               DEBUG_PRINT_HIGH("VIDIOC_S_CTRL: VPU_S_CTRL_IMAGE_ENHANCEMENT set to %d", ie->value);
   3638           }
   3639 #endif
   3640           break;
   3641         }
   3642 #ifdef FRC_ENABLE
   3643       case OMX_IndexVendorVideoFrameRate:
   3644        {
   3645 
   3646             OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   3647             DEBUG_PRINT_HIGH("OMX_IndexVendorVideoFrameRate %d", config->nFps);
   3648 
   3649             if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   3650                 if (config->bEnabled) {
   3651                     if ((config->nFps >> 16) > 0) {
   3652                         DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
   3653                                 config->nFps >> 16);
   3654                         Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   3655                                 drv_ctx.frame_rate.fps_denominator);
   3656 
   3657                         if (!drv_ctx.frame_rate.fps_numerator) {
   3658                             DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   3659                             drv_ctx.frame_rate.fps_numerator = 30;
   3660                         }
   3661 
   3662                         if (drv_ctx.frame_rate.fps_denominator) {
   3663                             drv_ctx.frame_rate.fps_numerator = (int)
   3664                                 drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   3665                         }
   3666 
   3667                         drv_ctx.frame_rate.fps_denominator = 1;
   3668                         frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   3669                             drv_ctx.frame_rate.fps_numerator;
   3670 
   3671                         struct v4l2_outputparm oparm;
   3672                         /*XXX: we're providing timing info as seconds per frame rather than frames
   3673                          * per second.*/
   3674                         oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   3675                         oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   3676 
   3677                         struct v4l2_streamparm sparm;
   3678                         memset(&sparm, 0, sizeof(struct v4l2_streamparm));
   3679                         sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3680                         sparm.parm.output = oparm;
   3681 #ifndef STUB_VPU
   3682                         if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_PARM, &sparm)) {
   3683                             DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   3684                                     performance might be affected");
   3685                             eRet = OMX_ErrorHardware;
   3686                         }
   3687 #endif
   3688                         client_set_fps = true;
   3689                     } else {
   3690                         DEBUG_PRINT_ERROR("Frame rate not supported.");
   3691                         eRet = OMX_ErrorUnsupportedSetting;
   3692                     }
   3693                 } else {
   3694                     DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   3695                     client_set_fps = false;
   3696                 }
   3697             } else { // 8084 doesn't support FRC (only 8092 does). only input framerate setting is supported.
   3698                 DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   3699                         (int)config->nPortIndex);
   3700                 eRet = OMX_ErrorBadPortIndex;
   3701             }
   3702 
   3703         }
   3704        break;
   3705 #endif
   3706       case OMX_IndexConfigCallbackRequest:
   3707        {
   3708             OMX_CONFIG_CALLBACKREQUESTTYPE *callbackRequest = (OMX_CONFIG_CALLBACKREQUESTTYPE *) configData;
   3709             DEBUG_PRINT_HIGH("OMX_IndexConfigCallbackRequest %d", callbackRequest->bEnable);
   3710 
   3711             if (callbackRequest->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   3712                 if ((callbackRequest->bEnable) && (OMX_QcomIndexConfigActiveRegionDetectionStatus == (OMX_QCOM_EXTN_INDEXTYPE)callbackRequest->nIndex))
   3713                 {
   3714                     m_ar_callback_setup  = true;
   3715                 }
   3716             }
   3717        }
   3718        break;
   3719       case OMX_IndexConfigCommonOutputCrop:
   3720           {
   3721               OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   3722               memcpy(&rectangle, rect, sizeof(OMX_CONFIG_RECTTYPE));
   3723               break;
   3724           }
   3725       default:
   3726           {
   3727               DEBUG_PRINT_ERROR("set_config: unknown param 0x%08x\n",configIndex);
   3728               eRet = OMX_ErrorBadParameter;
   3729           }
   3730   }
   3731 
   3732   return eRet;
   3733 }
   3734 
   3735 /* ======================================================================
   3736 FUNCTION
   3737   omx_vdpp::GetExtensionIndex
   3738 
   3739 DESCRIPTION
   3740   OMX GetExtensionIndex method implementaion.  <TBD>
   3741 
   3742 PARAMETERS
   3743   <TBD>.
   3744 
   3745 RETURN VALUE
   3746   OMX Error None if everything successful.
   3747 
   3748 ========================================================================== */
   3749 OMX_ERRORTYPE  omx_vdpp::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   3750                                                 OMX_IN OMX_STRING      paramName,
   3751                                                 OMX_OUT OMX_INDEXTYPE* indexType)
   3752 {
   3753     DEBUG_PRINT_LOW("omx_vdpp::get_extension_index %s\n", paramName);
   3754     if(m_state == OMX_StateInvalid)
   3755     {
   3756         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
   3757         return OMX_ErrorInvalidState;
   3758     }
   3759 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3760     else if(!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
   3761         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   3762         DEBUG_PRINT_HIGH("OMX.google.android.index.enableAndroidNativeBuffers");
   3763     }
   3764     else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
   3765         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   3766         DEBUG_PRINT_HIGH("OMX.google.android.index.useAndroidNativeBuffer2");
   3767     }
   3768     else if(!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
   3769         DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
   3770         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   3771         DEBUG_PRINT_HIGH("OMX.google.android.index.useAndroidNativeBuffer");
   3772     }
   3773     else if(!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
   3774         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   3775         DEBUG_PRINT_HIGH("OMX.google.android.index.getAndroidNativeBufferUsage");
   3776     }
   3777 #endif
   3778 
   3779     /* VIDPP extension
   3780      */
   3781     else if(!strncmp(paramName,
   3782                      OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS,
   3783                      sizeof(OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS) - 1))
   3784     {
   3785         DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION_STATUS 0x%x \n", OMX_QcomIndexConfigActiveRegionDetectionStatus);
   3786         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetectionStatus;
   3787     }
   3788     else if(!strncmp(paramName,
   3789                      OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION,
   3790                      sizeof(OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION) - 1))
   3791     {
   3792         DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_ACTIVE_REGION_DETECTION 0x%x \n", OMX_QcomIndexConfigActiveRegionDetection);
   3793         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigActiveRegionDetection;
   3794     }
   3795     else if(!strncmp(paramName,
   3796                      OMX_QCOM_INDEX_CONFIG_SCALING_MODE,
   3797                      sizeof(OMX_QCOM_INDEX_CONFIG_SCALING_MODE) - 1))
   3798     {
   3799         DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_SCALING_MODE 0x%x \n", OMX_QcomIndexConfigScalingMode);
   3800         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigScalingMode;
   3801     }
   3802     else if(!strncmp(paramName,
   3803                      OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION,
   3804                      sizeof(OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION) - 1))
   3805     {
   3806         DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_NOISEREDUCTION 0x%x \n", OMX_QcomIndexConfigNoiseReduction);
   3807         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigNoiseReduction;
   3808     }
   3809     else if(!strncmp(paramName,
   3810                      OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT,
   3811                      sizeof(OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT) - 1))
   3812     {
   3813         DEBUG_PRINT_LOW("get_extension_index OMX_QCOM_INDEX_CONFIG_IMAGEENHANCEMENT 0x%x \n", OMX_QcomIndexConfigImageEnhancement);
   3814         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigImageEnhancement;
   3815     }
   3816 
   3817 	else {
   3818         DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
   3819         return OMX_ErrorNotImplemented;
   3820     }
   3821     return OMX_ErrorNone;
   3822 }
   3823 
   3824 /* ======================================================================
   3825 FUNCTION
   3826   omx_vdpp::GetState
   3827 
   3828 DESCRIPTION
   3829   Returns the state information back to the caller.<TBD>
   3830 
   3831 PARAMETERS
   3832   <TBD>.
   3833 
   3834 RETURN VALUE
   3835   Error None if everything is successful.
   3836 ========================================================================== */
   3837 OMX_ERRORTYPE  omx_vdpp::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   3838                                        OMX_OUT OMX_STATETYPE* state)
   3839 {
   3840   *state = m_state;
   3841   DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
   3842   return OMX_ErrorNone;
   3843 }
   3844 
   3845 /* ======================================================================
   3846 FUNCTION
   3847   omx_vdpp::ComponentTunnelRequest
   3848 
   3849 DESCRIPTION
   3850   OMX Component Tunnel Request method implementation. <TBD>
   3851 
   3852 PARAMETERS
   3853   None.
   3854 
   3855 RETURN VALUE
   3856   OMX Error None if everything successful.
   3857 
   3858 ========================================================================== */
   3859 OMX_ERRORTYPE  omx_vdpp::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
   3860                                                      OMX_IN OMX_U32                        port,
   3861                                                      OMX_IN OMX_HANDLETYPE        peerComponent,
   3862                                                      OMX_IN OMX_U32                    peerPort,
   3863                                                      OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   3864 {
   3865   DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
   3866   return OMX_ErrorNotImplemented;
   3867 }
   3868 
   3869 OMX_ERRORTYPE  omx_vdpp::use_output_buffer(
   3870                          OMX_IN OMX_HANDLETYPE            hComp,
   3871                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   3872                          OMX_IN OMX_U32                   port,
   3873                          OMX_IN OMX_PTR                   appData,
   3874                          OMX_IN OMX_U32                   bytes,
   3875                          OMX_IN OMX_U8*                   buffer)
   3876 {
   3877   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3878   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   3879   unsigned                         i= 0; // Temporary counter
   3880   struct vdpp_setbuffer_cmd setbuffers;
   3881   OMX_PTR privateAppData = NULL;
   3882   private_handle_t *handle = NULL;
   3883   OMX_U8 *buff = buffer;
   3884   struct v4l2_buffer buf;
   3885   struct v4l2_plane plane[VIDEO_MAX_PLANES];
   3886   int extra_idx = 0;
   3887 
   3888   DEBUG_PRINT_HIGH("Inside omx_vdpp::use_output_buffer buffer = %p, bytes= %lu", buffer, bytes);
   3889 
   3890   if (!m_out_mem_ptr) {
   3891     DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers buffer = %p, bytes= %lu", buffer, bytes);
   3892     eRet = allocate_output_headers();
   3893   }
   3894 
   3895   if (eRet == OMX_ErrorNone) {
   3896     for(i=0; i< drv_ctx.op_buf.actualcount; i++) {
   3897       if(BITMASK_ABSENT(&m_out_bm_count,i))
   3898       {
   3899         break;
   3900       }
   3901     }
   3902   }
   3903 
   3904   if(i >= drv_ctx.op_buf.actualcount) {
   3905     DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
   3906     eRet = OMX_ErrorInsufficientResources;
   3907   }
   3908 
   3909   if (eRet == OMX_ErrorNone) {
   3910 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   3911     if(m_enable_android_native_buffers) {
   3912         DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 1\n");
   3913         if (m_use_android_native_buffers) {
   3914             DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 2\n");
   3915             UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   3916             sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   3917             handle = (private_handle_t *)nBuf->handle;
   3918             privateAppData = params->pAppPrivate;
   3919         } else {
   3920             DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 3\n");
   3921             handle = (private_handle_t *)buff;
   3922             privateAppData = appData;
   3923         }
   3924 
   3925         if(!handle) {
   3926             DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   3927             return OMX_ErrorBadParameter;
   3928         }
   3929 
   3930         if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   3931             DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   3932                               " expected %u, got %lu",
   3933                               drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
   3934             return OMX_ErrorBadParameter;
   3935         }
   3936 
   3937 #if defined(_ANDROID_ICS_)
   3938         native_buffer[i].nativehandle = handle;
   3939         native_buffer[i].privatehandle = handle;
   3940 #endif
   3941         drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   3942         drv_ctx.ptr_outputbuffer[i].offset = 0;
   3943         drv_ctx.ptr_outputbuffer[i].bufferaddr = NULL;
   3944         drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   3945         drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   3946         DEBUG_PRINT_HIGH("Use_op_buf:m_enable_android_native_buffers 5 drv_ctx.ptr_outputbuffer[i].bufferaddr = %p, size1=%d, size2=%d\n",
   3947                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   3948                 drv_ctx.op_buf.buffer_size,
   3949                 handle->size);
   3950     } else
   3951 #endif
   3952 
   3953     if (!ouput_egl_buffers && !m_use_output_pmem) {
   3954 #ifdef USE_ION
   3955         drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   3956                 drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   3957                 &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   3958                 &drv_ctx.op_buf_ion_info[i].fd_ion_data, 0);
   3959         if(drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   3960           DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   3961           return OMX_ErrorInsufficientResources;
   3962         }
   3963         drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   3964           drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   3965 #else
   3966         drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   3967           open (MEM_DEVICE,O_RDWR);
   3968 
   3969         if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   3970           DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   3971           return OMX_ErrorInsufficientResources;
   3972         }
   3973 
   3974         if(!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   3975           drv_ctx.op_buf.buffer_size,
   3976           drv_ctx.op_buf.alignment))
   3977         {
   3978           DEBUG_PRINT_ERROR(" align_pmem_buffers() failed");
   3979           close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   3980           return OMX_ErrorInsufficientResources;
   3981         }
   3982 #endif
   3983         {
   3984             drv_ctx.ptr_outputbuffer[i].bufferaddr =
   3985               (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   3986               PROT_READ|PROT_WRITE, MAP_SHARED,
   3987               drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   3988             if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   3989                 close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   3990 #ifdef USE_ION
   3991                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   3992 #endif
   3993               DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
   3994               return OMX_ErrorInsufficientResources;
   3995             }
   3996         }
   3997         drv_ctx.ptr_outputbuffer[i].offset = 0;
   3998         privateAppData = appData;
   3999      }
   4000      else {
   4001 
   4002        DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   4003         if (!appData || !bytes ) {
   4004           if(!buffer) {
   4005               DEBUG_PRINT_ERROR(" Bad parameters for use buffer in EGL image case");
   4006               return OMX_ErrorBadParameter;
   4007           }
   4008         }
   4009 
   4010         OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   4011         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   4012         pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   4013         if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
   4014             !pmem_list->nEntries ||
   4015             pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4016           DEBUG_PRINT_ERROR(" Pmem info not valid in use buffer");
   4017           return OMX_ErrorBadParameter;
   4018         }
   4019         pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   4020                     pmem_list->entryList->entry;
   4021         DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   4022                           pmem_info->pmem_fd);
   4023         drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   4024         drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   4025         drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   4026         drv_ctx.ptr_outputbuffer[i].mmaped_size =
   4027         drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   4028         privateAppData = appData;
   4029      }
   4030 
   4031      *bufferHdr = (m_out_mem_ptr + i );
   4032 
   4033      memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   4034              sizeof (vdpp_bufferpayload));
   4035 
   4036      DEBUG_PRINT_HIGH(" Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   4037                        drv_ctx.ptr_outputbuffer[i].bufferaddr,
   4038                        drv_ctx.ptr_outputbuffer[i].pmem_fd );
   4039 #ifndef STUB_VPU
   4040     DEBUG_PRINT_LOW("use_output_buffer: i = %d, streaming[CAPTURE_PORT] = %d ", i, streaming[CAPTURE_PORT]);
   4041     // stream on output port
   4042     if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   4043 	    enum v4l2_buf_type buf_type;
   4044 	    buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4045 	    if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMON,&buf_type)) {
   4046 		    DEBUG_PRINT_ERROR("V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE STREAMON failed \n ");
   4047 		    return OMX_ErrorInsufficientResources;
   4048 	    } else {
   4049 		    streaming[CAPTURE_PORT] = true;
   4050 		    DEBUG_PRINT_HIGH("V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE STREAMON Successful \n ");
   4051 	    }
   4052     }
   4053 #endif
   4054 
   4055      (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   4056      if (m_enable_android_native_buffers) {
   4057        DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   4058        (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   4059      } else {
   4060        (*bufferHdr)->pBuffer = buff;
   4061      }
   4062      (*bufferHdr)->pAppPrivate = privateAppData;
   4063      BITMASK_SET(&m_out_bm_count,i);
   4064   }
   4065   return eRet;
   4066 }
   4067 
   4068 
   4069 /* ======================================================================
   4070 FUNCTION
   4071   omx_vdpp::use_input_heap_buffers
   4072 
   4073 DESCRIPTION
   4074   OMX Use Buffer Heap allocation method implementation.
   4075 
   4076 PARAMETERS
   4077   <TBD>.
   4078 
   4079 RETURN VALUE
   4080   OMX Error None , if everything successful.
   4081 
   4082 ========================================================================== */
   4083 OMX_ERRORTYPE  omx_vdpp::use_input_heap_buffers(
   4084                          OMX_IN OMX_HANDLETYPE            hComp,
   4085                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4086                          OMX_IN OMX_U32                   port,
   4087                          OMX_IN OMX_PTR                   appData,
   4088                          OMX_IN OMX_U32                   bytes,
   4089                          OMX_IN OMX_U8*                   buffer)
   4090 {
   4091   OMX_PTR privateAppData = NULL;
   4092 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   4093   private_handle_t *handle = NULL;
   4094 #endif
   4095   OMX_U8 *buff = buffer;
   4096 
   4097   DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
   4098   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4099   if(!m_inp_heap_ptr)
   4100   {
   4101   DEBUG_PRINT_LOW("Inside %s 0, %p\n", __FUNCTION__, buffer);
   4102     m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   4103                calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4104                drv_ctx.ip_buf.actualcount);
   4105   }
   4106 
   4107   if(!m_phdr_pmem_ptr)
   4108   {
   4109   DEBUG_PRINT_LOW("Inside %s 0-1, %p\n", __FUNCTION__, buffer);
   4110     m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   4111                calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4112                drv_ctx.ip_buf.actualcount);
   4113   }
   4114   if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
   4115   {
   4116     DEBUG_PRINT_ERROR("Insufficent memory");
   4117     eRet = OMX_ErrorInsufficientResources;
   4118   }
   4119   else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
   4120   {
   4121     DEBUG_PRINT_LOW("Inside %s 2 m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d\n", __FUNCTION__, m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
   4122     input_use_buffer = true;
   4123     memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   4124     // update this buffer for native window buffer in etb
   4125     // OMXNodeInstance::useGraphicBuffer2_l check if pBuffer and pAppPrivate are
   4126     // the same value as passed in. If not, useGraphicBuffer2_l will exit on error
   4127     //
   4128     m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   4129     m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   4130     m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   4131     m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   4132     m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   4133     // save mmapped native window buffer address to pPlatformPrivate
   4134     // use this mmaped buffer address in etb_proxy
   4135 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   4136     /*if(m_enable_android_native_buffers) */{
   4137         if (m_use_android_native_buffers) {
   4138             UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   4139             sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   4140             handle = (private_handle_t *)nBuf->handle;
   4141             privateAppData = params->pAppPrivate;
   4142         } else {
   4143             handle = (private_handle_t *)buff;
   4144             privateAppData = appData;
   4145             //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 3\n");
   4146         }
   4147 
   4148         if(!handle) {
   4149             DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   4150             return OMX_ErrorBadParameter;
   4151         }
   4152 
   4153         if ((OMX_U32)handle->size < drv_ctx.ip_buf.buffer_size) {
   4154             DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   4155                               " expected %u, got %lu",
   4156                               drv_ctx.ip_buf.buffer_size, (OMX_U32)handle->size);
   4157             return OMX_ErrorBadParameter;
   4158         }
   4159 
   4160         if (!m_use_android_native_buffers) {
   4161                 buff =  (OMX_U8*)mmap(0, handle->size,
   4162                                       PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   4163                 //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 4 buff = %p\n", buff);
   4164                 if (buff == MAP_FAILED) {
   4165                   DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   4166                   return OMX_ErrorInsufficientResources;
   4167                 }
   4168         }
   4169         // we only need to copy this buffer (read only), no need to preserver this handle
   4170         // this handle is saved for write-unlock in use_output_buffer case
   4171 #if defined(_ANDROID_ICS_)
   4172         //native_buffer[i].nativehandle = handle;
   4173         //native_buffer[i].privatehandle = handle;
   4174 #endif
   4175         m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate = buff;
   4176         //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 5 m_inp_heap_ptr = %p, m_inp_heap_ptr[%lu].pPlatformPrivate = %p, m_inp_heap_ptr[%lu].pBuffer = %p\n",
   4177         //    m_inp_heap_ptr, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pBuffer);
   4178     }
   4179 #endif
   4180     *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   4181     // user passes buffer in, but we need ION buffer
   4182     //DEBUG_PRINT_LOW("Inside %s 6 *bufferHdr = %p, byts = %lu \n", __FUNCTION__, *bufferHdr, bytes);
   4183     eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   4184     DEBUG_PRINT_HIGH(" Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   4185     if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
   4186                 (unsigned)NULL, (unsigned)NULL))
   4187     {
   4188       DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   4189       return OMX_ErrorInsufficientResources;
   4190     }
   4191     m_in_alloc_cnt++;
   4192   }
   4193   else
   4194   {
   4195     DEBUG_PRINT_ERROR("All i/p buffers have been set! m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d", m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
   4196     eRet = OMX_ErrorInsufficientResources;
   4197   }
   4198   return eRet;
   4199 }
   4200 
   4201 
   4202 /* ======================================================================
   4203 FUNCTION
   4204   omx_vdpp::use_input_buffers
   4205 
   4206 DESCRIPTION
   4207   OMX Use Buffer method implementation.
   4208 
   4209 PARAMETERS
   4210   <TBD>.
   4211 
   4212 RETURN VALUE
   4213   OMX Error None , if everything successful.
   4214 
   4215 ========================================================================== */
   4216 OMX_ERRORTYPE  omx_vdpp::use_input_buffers(
   4217                          OMX_IN OMX_HANDLETYPE            hComp,
   4218                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4219                          OMX_IN OMX_U32                   port,
   4220                          OMX_IN OMX_PTR                   appData,
   4221                          OMX_IN OMX_U32                   bytes,
   4222                          OMX_IN OMX_U8*                   buffer)
   4223 {
   4224   OMX_PTR privateAppData = NULL;
   4225   OMX_BUFFERHEADERTYPE *input = NULL;
   4226 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   4227   private_handle_t *handle = NULL;
   4228 #endif
   4229   OMX_U8 *buff = buffer;
   4230   unsigned int  i = 0;
   4231 
   4232   DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
   4233   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4234 
   4235   if(!m_inp_heap_ptr)
   4236   {
   4237   DEBUG_PRINT_LOW("Inside %s 0, %p\n", __FUNCTION__, buffer);
   4238     m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   4239                calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4240                drv_ctx.ip_buf.actualcount);
   4241   }
   4242 
   4243   if(!m_phdr_pmem_ptr)
   4244   {
   4245   DEBUG_PRINT_LOW("Inside %s 0-1, %p\n", __FUNCTION__, buffer);
   4246     m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   4247                calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4248                drv_ctx.ip_buf.actualcount);
   4249   }
   4250 
   4251   if(!m_inp_heap_ptr || !m_phdr_pmem_ptr)
   4252   {
   4253     DEBUG_PRINT_ERROR("Insufficent memory");
   4254     eRet = OMX_ErrorInsufficientResources;
   4255   }
   4256   else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount)
   4257   {
   4258     DEBUG_PRINT_LOW("Inside %s 2 m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d\n", __FUNCTION__, m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
   4259     input_use_buffer = true;
   4260     memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   4261     // update this buffer for native window buffer in etb
   4262     // OMXNodeInstance::useGraphicBuffer2_l check if pBuffer and pAppPrivate are
   4263     // the same value as passed in. If not, useGraphicBuffer2_l will exit on error
   4264     //
   4265     m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   4266     m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   4267     m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   4268     m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   4269     m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   4270     // save mmapped native window buffer address to pPlatformPrivate
   4271     // use this mmaped buffer address in etb_proxy
   4272 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   4273     /*if(m_enable_android_native_buffers) */{
   4274         if (m_use_android_native_buffers) {
   4275             UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   4276             sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   4277             handle = (private_handle_t *)nBuf->handle;
   4278             privateAppData = params->pAppPrivate;
   4279         } else {
   4280             handle = (private_handle_t *)buff;
   4281             privateAppData = appData;
   4282             DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 3\n");
   4283         }
   4284 
   4285         if(!handle) {
   4286             DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   4287             return OMX_ErrorBadParameter;
   4288         }
   4289 
   4290         if ((OMX_U32)handle->size < drv_ctx.ip_buf.buffer_size) {
   4291             DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   4292                               " expected %u, got %lu",
   4293                               drv_ctx.ip_buf.buffer_size, (OMX_U32)handle->size);
   4294             return OMX_ErrorBadParameter;
   4295         }
   4296 
   4297         if (!m_use_android_native_buffers) {
   4298                 buff =  (OMX_U8*)mmap(0, (handle->size - drv_ctx.ip_buf.frame_size),
   4299                                       PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, drv_ctx.ip_buf.frame_size);
   4300 
   4301                 DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 4 buff = %p, size1=%d, size2=%d\n", buff,
   4302                         drv_ctx.ip_buf.buffer_size,
   4303                                      handle->size);
   4304                 if (buff == MAP_FAILED) {
   4305                   DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   4306                   return OMX_ErrorInsufficientResources;
   4307                 }
   4308         }
   4309         // we only need to copy this buffer (read only), no need to preserver this handle
   4310         // this handle is saved for write-unlock in use_output_buffer case
   4311 #if defined(_ANDROID_ICS_)
   4312         //native_buffer[i].nativehandle = handle;
   4313         //native_buffer[i].privatehandle = handle;
   4314 #endif
   4315         m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate = buff;
   4316         //DEBUG_PRINT_LOW("omx_vdpp::use_input_heap_buffers 5 m_inp_heap_ptr = %p, m_inp_heap_ptr[%lu].pPlatformPrivate = %p, m_inp_heap_ptr[%lu].pBuffer = %p\n",
   4317         //    m_inp_heap_ptr, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pPlatformPrivate, m_in_alloc_cnt, m_inp_heap_ptr[m_in_alloc_cnt].pBuffer);
   4318     }
   4319 #endif
   4320    *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   4321 
   4322   if(!m_inp_mem_ptr)
   4323   {
   4324     DEBUG_PRINT_HIGH(" Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
   4325       drv_ctx.ip_buf.actualcount,
   4326       drv_ctx.ip_buf.buffer_size);
   4327 
   4328     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   4329     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   4330 
   4331     if (m_inp_mem_ptr == NULL)
   4332     {
   4333       return OMX_ErrorInsufficientResources;
   4334     }
   4335 
   4336     drv_ctx.ptr_inputbuffer = (struct vdpp_bufferpayload *) \
   4337     calloc ((sizeof (struct vdpp_bufferpayload)),drv_ctx.ip_buf.actualcount);
   4338 
   4339     if (drv_ctx.ptr_inputbuffer == NULL)
   4340     {
   4341       return OMX_ErrorInsufficientResources;
   4342     }
   4343   }
   4344 
   4345   for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
   4346   {
   4347     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   4348     {
   4349       DEBUG_PRINT_LOW(" Free Input Buffer Index %d",i);
   4350       break;
   4351     }
   4352   }
   4353 
   4354   if(i < drv_ctx.ip_buf.actualcount)
   4355   {
   4356     struct v4l2_buffer buf;
   4357     struct v4l2_plane plane;
   4358     int rc;
   4359 
   4360     m_phdr_pmem_ptr[m_in_alloc_cnt] = (m_inp_mem_ptr + i);
   4361 
   4362     drv_ctx.ptr_inputbuffer [i].bufferaddr = buff;
   4363     drv_ctx.ptr_inputbuffer [i].pmem_fd = handle->fd;
   4364     drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   4365     drv_ctx.ptr_inputbuffer [i].mmaped_size = handle->size - drv_ctx.ip_buf.frame_size;
   4366     drv_ctx.ptr_inputbuffer [i].offset = 0;
   4367 
   4368     input = m_phdr_pmem_ptr[m_in_alloc_cnt];
   4369     BITMASK_SET(&m_inp_bm_count,i);
   4370     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Buffer address %p of pmem",*bufferHdr);
   4371 
   4372     input->pBuffer           = (OMX_U8 *)buff;
   4373     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   4374     input->nVersion.nVersion = OMX_SPEC_VERSION;
   4375     input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   4376     input->pAppPrivate       = appData;
   4377     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   4378     input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; // used in empty_this_buffer_proxy
   4379 
   4380     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer input->pBuffer %p of pmem, input->pInputPortPrivate = %p",input->pBuffer, input->pInputPortPrivate);
   4381     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer memset drv_ctx.ip_buf.buffer_size = %d\n", drv_ctx.ip_buf.buffer_size);
   4382 
   4383   }
   4384   else
   4385   {
   4386     DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   4387     eRet = OMX_ErrorInsufficientResources;
   4388   }
   4389 
   4390   if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
   4391             (unsigned)NULL, (unsigned)NULL))
   4392   {
   4393     DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   4394     return OMX_ErrorInsufficientResources;
   4395   }
   4396     m_in_alloc_cnt++;
   4397   }
   4398   else
   4399   {
   4400     DEBUG_PRINT_ERROR("All i/p buffers have been set! m_in_alloc_cnt = %lu, drv_ctx.ip_buf.actualcount = %d", m_in_alloc_cnt, drv_ctx.ip_buf.actualcount);
   4401     eRet = OMX_ErrorInsufficientResources;
   4402   }
   4403   return eRet;
   4404 }
   4405 
   4406 /* ======================================================================
   4407 FUNCTION
   4408   omx_vdpp::UseBuffer
   4409 
   4410 DESCRIPTION
   4411   OMX Use Buffer method implementation.
   4412 
   4413 PARAMETERS
   4414   <TBD>.
   4415 
   4416 RETURN VALUE
   4417   OMX Error None , if everything successful.
   4418 
   4419 ========================================================================== */
   4420 OMX_ERRORTYPE  omx_vdpp::use_buffer(
   4421                          OMX_IN OMX_HANDLETYPE            hComp,
   4422                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4423                          OMX_IN OMX_U32                   port,
   4424                          OMX_IN OMX_PTR                   appData,
   4425                          OMX_IN OMX_U32                   bytes,
   4426                          OMX_IN OMX_U8*                   buffer)
   4427 {
   4428   OMX_ERRORTYPE error = OMX_ErrorNone;
   4429   struct vdpp_setbuffer_cmd setbuffers;
   4430 
   4431   if ((bufferHdr == NULL) || (bytes == 0) || (/*!secure_mode && */buffer == NULL))
   4432   {
   4433       DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
   4434       return OMX_ErrorBadParameter;
   4435   }
   4436   if(m_state == OMX_StateInvalid)
   4437   {
   4438     DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
   4439     return OMX_ErrorInvalidState;
   4440   }
   4441   if(port == OMX_CORE_INPUT_PORT_INDEX)
   4442     //error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   4443     error = use_input_buffers(hComp, bufferHdr, port, appData, bytes, buffer);  // option to use vdec buffer
   4444 
   4445   else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   4446     error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   4447   else
   4448   {
   4449     DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   4450     error = OMX_ErrorBadPortIndex;
   4451   }
   4452   DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
   4453   if(error == OMX_ErrorNone)
   4454   {
   4455     if(allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   4456     {
   4457       // Send the callback now
   4458       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   4459       post_event(OMX_CommandStateSet,OMX_StateIdle,
   4460                          OMX_COMPONENT_GENERATE_EVENT);
   4461     }
   4462     if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   4463        BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   4464     {
   4465       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   4466       post_event(OMX_CommandPortEnable,
   4467           OMX_CORE_INPUT_PORT_INDEX,
   4468           OMX_COMPONENT_GENERATE_EVENT);
   4469     }
   4470     else if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   4471             BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   4472     {
   4473       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   4474       post_event(OMX_CommandPortEnable,
   4475                  OMX_CORE_OUTPUT_PORT_INDEX,
   4476                  OMX_COMPONENT_GENERATE_EVENT);
   4477     }
   4478   }
   4479   DEBUG_PRINT_LOW("Use Buffer error = %d", error);
   4480   return error;
   4481 }
   4482 
   4483 OMX_ERRORTYPE omx_vdpp::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   4484 {
   4485   unsigned int index = 0;
   4486   if (bufferHdr == NULL || m_inp_mem_ptr == NULL)
   4487   {
   4488     return OMX_ErrorBadParameter;
   4489   }
   4490 
   4491   index = bufferHdr - m_inp_mem_ptr;
   4492 
   4493   // decrease m_in_alloc_cnt so use_input_heap_buffer can be called
   4494   // again after port re-enable
   4495   m_in_alloc_cnt--;
   4496   DEBUG_PRINT_LOW("free_input_buffer Free Input Buffer index = %d, m_in_alloc_cnt = %lu",index, m_in_alloc_cnt);
   4497 
   4498   if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   4499       DEBUG_PRINT_LOW("Free Input ION Buffer index = %d",index);
   4500       if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
   4501           struct vdpp_setbuffer_cmd setbuffers;
   4502           setbuffers.buffer_type = VDPP_BUFFER_TYPE_INPUT;
   4503           memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   4504                   sizeof (vdpp_bufferpayload));
   4505           {
   4506               DEBUG_PRINT_LOW(" unmap the input buffer fd=%d",
   4507                       drv_ctx.ptr_inputbuffer[index].pmem_fd);
   4508               DEBUG_PRINT_LOW(" unmap the input buffer size=%d  address = %p",
   4509                       drv_ctx.ptr_inputbuffer[index].mmaped_size,
   4510                       drv_ctx.ptr_inputbuffer[index].bufferaddr);
   4511               munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   4512                       drv_ctx.ptr_inputbuffer[index].mmaped_size);
   4513           }
   4514 
   4515           // If drv_ctx.ip_buf_ion_info is NULL then ION buffer is passed from upper layer.
   4516           // don't close fd and free this buffer, leave upper layer close and free this buffer
   4517           drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   4518           if(drv_ctx.ip_buf_ion_info != NULL)
   4519           {
   4520               close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
   4521       #ifdef USE_ION
   4522               free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   4523       #endif
   4524           }
   4525 
   4526       }
   4527   }
   4528   return OMX_ErrorNone;
   4529 }
   4530 
   4531 OMX_ERRORTYPE omx_vdpp::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   4532 {
   4533   unsigned int index = 0;
   4534 
   4535   if (bufferHdr == NULL || m_out_mem_ptr == NULL)
   4536   {
   4537     return OMX_ErrorBadParameter;
   4538   }
   4539 
   4540   index = bufferHdr - m_out_mem_ptr;
   4541   DEBUG_PRINT_LOW(" Free output Buffer index = %d",index);
   4542 
   4543   if (index < drv_ctx.op_buf.actualcount
   4544       && drv_ctx.ptr_outputbuffer)
   4545   {
   4546     DEBUG_PRINT_LOW(" Free output Buffer index = %d addr = %p", index,
   4547                     drv_ctx.ptr_outputbuffer[index].bufferaddr);
   4548 
   4549     struct vdpp_setbuffer_cmd setbuffers;
   4550     setbuffers.buffer_type = VDPP_BUFFER_TYPE_OUTPUT;
   4551     memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   4552         sizeof (vdpp_bufferpayload));
   4553 #ifdef _ANDROID_
   4554     if(m_enable_android_native_buffers) {
   4555         DEBUG_PRINT_LOW(" Free output Buffer android pmem_fd=%d", drv_ctx.ptr_outputbuffer[index].pmem_fd);
   4556         if(drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   4557             DEBUG_PRINT_LOW(" Free output Buffer android 2 bufferaddr=%p, mmaped_size=%d",
   4558                     drv_ctx.ptr_outputbuffer[index].bufferaddr,
   4559                     drv_ctx.ptr_outputbuffer[index].mmaped_size);
   4560             if( NULL != drv_ctx.ptr_outputbuffer[index].bufferaddr)
   4561             {
   4562                 munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   4563                         drv_ctx.ptr_outputbuffer[index].mmaped_size);
   4564             }
   4565         }
   4566         drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   4567     } else {
   4568 #endif
   4569         if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem)
   4570         {
   4571             {
   4572                 DEBUG_PRINT_LOW(" unmap the output buffer fd = %d",
   4573                         drv_ctx.ptr_outputbuffer[index].pmem_fd);
   4574                 DEBUG_PRINT_LOW(" unmap the ouput buffer size=%d  address = %p",
   4575                         drv_ctx.ptr_outputbuffer[index].mmaped_size * drv_ctx.op_buf.actualcount,
   4576                         drv_ctx.ptr_outputbuffer[index].bufferaddr);
   4577                 munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr,
   4578                         drv_ctx.ptr_outputbuffer[index].mmaped_size * drv_ctx.op_buf.actualcount);
   4579             }
   4580             close (drv_ctx.ptr_outputbuffer[index].pmem_fd);
   4581             drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   4582 #ifdef USE_ION
   4583             free_ion_memory(&drv_ctx.op_buf_ion_info[index]);
   4584 #endif
   4585         }
   4586 #ifdef _ANDROID_
   4587     }
   4588 #endif
   4589     if (release_output_done()) {
   4590       //free_extradata();
   4591     }
   4592   }
   4593 
   4594   return OMX_ErrorNone;
   4595 
   4596 }
   4597 
   4598 OMX_ERRORTYPE omx_vdpp::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   4599                                          OMX_BUFFERHEADERTYPE **bufferHdr,
   4600                                          OMX_U32              port,
   4601                                          OMX_PTR              appData,
   4602                                          OMX_U32              bytes)
   4603 {
   4604   OMX_BUFFERHEADERTYPE *input = NULL;
   4605   unsigned char *buf_addr = NULL;
   4606   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4607   unsigned   i = 0;
   4608 
   4609   /* Sanity Check*/
   4610   if (bufferHdr == NULL)
   4611   {
   4612     return OMX_ErrorBadParameter;
   4613   }
   4614 
   4615   if (m_inp_heap_ptr == NULL)
   4616   {
   4617     m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   4618                      calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4619                      drv_ctx.ip_buf.actualcount);
   4620     m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   4621                      calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4622                      drv_ctx.ip_buf.actualcount);
   4623 
   4624     if ((m_inp_heap_ptr == NULL) || (m_phdr_pmem_ptr == NULL))
   4625     {
   4626       DEBUG_PRINT_ERROR(" m_inp_heap_ptr Allocation failed ");
   4627       return OMX_ErrorInsufficientResources;
   4628     }
   4629   }
   4630 
   4631   /*Find a Free index*/
   4632   for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
   4633   {
   4634     if(BITMASK_ABSENT(&m_heap_inp_bm_count,i))
   4635     {
   4636       DEBUG_PRINT_LOW(" Free Input Buffer Index %d",i);
   4637       break;
   4638     }
   4639   }
   4640 
   4641   if (i < drv_ctx.ip_buf.actualcount)
   4642   {
   4643     buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   4644 
   4645     if (buf_addr == NULL)
   4646     {
   4647       return OMX_ErrorInsufficientResources;
   4648     }
   4649 
   4650     *bufferHdr = (m_inp_heap_ptr + i);
   4651     input = *bufferHdr;
   4652     BITMASK_SET(&m_heap_inp_bm_count,i);
   4653 
   4654     input->pBuffer           = (OMX_U8 *)buf_addr;
   4655     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   4656     input->nVersion.nVersion = OMX_SPEC_VERSION;
   4657     input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   4658     input->pAppPrivate       = appData;
   4659     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   4660     DEBUG_PRINT_LOW(" Address of Heap Buffer %p",*bufferHdr );
   4661     eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   4662     DEBUG_PRINT_LOW(" Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   4663     /*Add the Buffers to freeq*/
   4664     if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
   4665                 (unsigned)NULL, (unsigned)NULL))
   4666     {
   4667       DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   4668       return OMX_ErrorInsufficientResources;
   4669     }
   4670   }
   4671   else
   4672   {
   4673     return OMX_ErrorBadParameter;
   4674   }
   4675 
   4676   return eRet;
   4677 
   4678 }
   4679 
   4680 /* ======================================================================
   4681 FUNCTION
   4682   omx_vdpp::AllocateInputBuffer
   4683 
   4684 DESCRIPTION
   4685   Helper function for allocate buffer in the input pin
   4686 
   4687 PARAMETERS
   4688   None.
   4689 
   4690 RETURN VALUE
   4691   true/false
   4692 
   4693 ========================================================================== */
   4694 OMX_ERRORTYPE  omx_vdpp::allocate_input_buffer(
   4695                          OMX_IN OMX_HANDLETYPE            hComp,
   4696                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4697                          OMX_IN OMX_U32                   port,
   4698                          OMX_IN OMX_PTR                   appData,
   4699                          OMX_IN OMX_U32                   bytes)
   4700 {
   4701 
   4702   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4703   struct vdpp_setbuffer_cmd setbuffers;
   4704   OMX_BUFFERHEADERTYPE *input = NULL;
   4705   unsigned   i = 0;
   4706   unsigned char *buf_addr = NULL;
   4707   int pmem_fd = -1;
   4708 
   4709   if(bytes != drv_ctx.ip_buf.buffer_size)
   4710   {
   4711     DEBUG_PRINT_LOW(" Requested Size is wrong %lu expected is %d",
   4712       bytes, drv_ctx.ip_buf.buffer_size);
   4713      return OMX_ErrorBadParameter;
   4714   }
   4715 
   4716   if(!m_inp_mem_ptr)
   4717   {
   4718     DEBUG_PRINT_HIGH(" Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
   4719       drv_ctx.ip_buf.actualcount,
   4720       drv_ctx.ip_buf.buffer_size);
   4721 
   4722     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   4723     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   4724 
   4725     if (m_inp_mem_ptr == NULL)
   4726     {
   4727       return OMX_ErrorInsufficientResources;
   4728     }
   4729 
   4730     drv_ctx.ptr_inputbuffer = (struct vdpp_bufferpayload *) \
   4731     calloc ((sizeof (struct vdpp_bufferpayload)),drv_ctx.ip_buf.actualcount);
   4732 
   4733     if (drv_ctx.ptr_inputbuffer == NULL)
   4734     {
   4735       return OMX_ErrorInsufficientResources;
   4736     }
   4737 #ifdef USE_ION
   4738     drv_ctx.ip_buf_ion_info = (struct vdpp_ion *) \
   4739     calloc ((sizeof (struct vdpp_ion)),drv_ctx.ip_buf.actualcount);
   4740 
   4741     if (drv_ctx.ip_buf_ion_info == NULL)
   4742     {
   4743       return OMX_ErrorInsufficientResources;
   4744     }
   4745 #endif
   4746 
   4747     for (i=0; i < drv_ctx.ip_buf.actualcount; i++)
   4748     {
   4749       drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   4750 #ifdef USE_ION
   4751       drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   4752 #endif
   4753     }
   4754   }
   4755 
   4756   for(i=0; i< drv_ctx.ip_buf.actualcount; i++)
   4757   {
   4758     if(BITMASK_ABSENT(&m_inp_bm_count,i))
   4759     {
   4760       DEBUG_PRINT_LOW(" Free Input Buffer Index %d",i);
   4761       break;
   4762     }
   4763   }
   4764 
   4765   if(i < drv_ctx.ip_buf.actualcount)
   4766   {
   4767     struct v4l2_buffer buf;
   4768     struct v4l2_plane plane;
   4769     int rc;
   4770     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Allocate input Buffer, drv_ctx.ip_buf.buffer_size = %d", drv_ctx.ip_buf.buffer_size);
   4771 #ifdef USE_ION
   4772  drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   4773                     drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   4774                     &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   4775 		    &drv_ctx.ip_buf_ion_info[i].fd_ion_data, 0);
   4776     if(drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   4777         return OMX_ErrorInsufficientResources;
   4778      }
   4779     pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   4780 #endif
   4781 
   4782     {
   4783         buf_addr = (unsigned char *)mmap(NULL,
   4784           drv_ctx.ip_buf.buffer_size,
   4785           PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   4786 
   4787         if (buf_addr == MAP_FAILED)
   4788         {
   4789             close(pmem_fd);
   4790 #ifdef USE_ION
   4791             free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   4792 #endif
   4793           DEBUG_PRINT_ERROR(" Map Failed to allocate input buffer");
   4794           return OMX_ErrorInsufficientResources;
   4795         }
   4796     }
   4797     *bufferHdr = (m_inp_mem_ptr + i);
   4798 
   4799     drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   4800     drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   4801     drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   4802     drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   4803     drv_ctx.ptr_inputbuffer [i].offset = 0;
   4804 
   4805     input = *bufferHdr;
   4806     BITMASK_SET(&m_inp_bm_count,i);
   4807     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer Buffer address %p of pmem",*bufferHdr);
   4808 
   4809     input->pBuffer           = (OMX_U8 *)buf_addr;
   4810     input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   4811     input->nVersion.nVersion = OMX_SPEC_VERSION;
   4812     input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   4813     input->pAppPrivate       = appData;
   4814     input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   4815     input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i]; // used in empty_this_buffer_proxy
   4816 
   4817     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer input->pBuffer %p of pmem, input->pInputPortPrivate = %p",input->pBuffer, input->pInputPortPrivate);
   4818     memset(buf_addr, 0, drv_ctx.ip_buf.buffer_size);
   4819     DEBUG_PRINT_LOW("omx_vdpp::allocate_input_buffer memset drv_ctx.ip_buf.buffer_size = %d\n", drv_ctx.ip_buf.buffer_size);
   4820   }
   4821   else
   4822   {
   4823     DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   4824     eRet = OMX_ErrorInsufficientResources;
   4825   }
   4826   return eRet;
   4827 }
   4828 
   4829 
   4830 /* ======================================================================
   4831 FUNCTION
   4832   omx_vdpp::AllocateOutputBuffer
   4833 
   4834 DESCRIPTION
   4835   Helper fn for AllocateBuffer in the output pin
   4836 
   4837 PARAMETERS
   4838   <TBD>.
   4839 
   4840 RETURN VALUE
   4841   OMX Error None if everything went well.
   4842 
   4843 ========================================================================== */
   4844 OMX_ERRORTYPE  omx_vdpp::allocate_output_buffer(
   4845                          OMX_IN OMX_HANDLETYPE            hComp,
   4846                          OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4847                          OMX_IN OMX_U32                   port,
   4848                          OMX_IN OMX_PTR                   appData,
   4849                          OMX_IN OMX_U32                   bytes)
   4850 {
   4851   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4852   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   4853   unsigned                         i= 0; // Temporary counter
   4854   struct vdpp_setbuffer_cmd setbuffers;
   4855   int extra_idx = 0;
   4856 #ifdef USE_ION
   4857   int ion_device_fd =-1;
   4858   struct ion_allocation_data ion_alloc_data;
   4859   struct ion_fd_data fd_ion_data;
   4860 #endif
   4861   if(!m_out_mem_ptr)
   4862   {
   4863     DEBUG_PRINT_HIGH(" Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
   4864       drv_ctx.op_buf.actualcount,
   4865       drv_ctx.op_buf.buffer_size);
   4866     int nBufHdrSize        = 0;
   4867     int pmem_fd = -1;
   4868     unsigned char *pmem_baseaddress = NULL;
   4869 
   4870     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
   4871       drv_ctx.op_buf.actualcount);
   4872     nBufHdrSize        = drv_ctx.op_buf.actualcount *
   4873                          sizeof(OMX_BUFFERHEADERTYPE);
   4874 #ifdef USE_ION
   4875  ion_device_fd = alloc_map_ion_memory(
   4876                     drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
   4877                     drv_ctx.op_buf.alignment,
   4878                     &ion_alloc_data, &fd_ion_data, 0);
   4879     if (ion_device_fd < 0) {
   4880         return OMX_ErrorInsufficientResources;
   4881     }
   4882     pmem_fd = fd_ion_data.fd;
   4883 #endif
   4884 
   4885    {
   4886         pmem_baseaddress = (unsigned char *)mmap(NULL,
   4887                            (drv_ctx.op_buf.buffer_size *
   4888                             drv_ctx.op_buf.actualcount),
   4889                             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   4890         if (pmem_baseaddress == MAP_FAILED)
   4891         {
   4892           DEBUG_PRINT_ERROR(" MMAP failed for Size %d",
   4893           drv_ctx.op_buf.buffer_size);
   4894           close(pmem_fd);
   4895 #ifdef USE_ION
   4896           free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   4897 #endif
   4898           return OMX_ErrorInsufficientResources;
   4899         }
   4900     }
   4901 
   4902     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   4903 
   4904     drv_ctx.ptr_outputbuffer = (struct vdpp_bufferpayload *)\
   4905       calloc (sizeof(struct vdpp_bufferpayload),
   4906       drv_ctx.op_buf.actualcount);
   4907     drv_ctx.ptr_respbuffer = (struct vdpp_output_frameinfo  *)\
   4908       calloc (sizeof (struct vdpp_output_frameinfo),
   4909       drv_ctx.op_buf.actualcount);
   4910 #ifdef USE_ION
   4911     drv_ctx.op_buf_ion_info = (struct vdpp_ion *)\
   4912       calloc (sizeof(struct vdpp_ion),
   4913       drv_ctx.op_buf.actualcount);
   4914 
   4915       if (!drv_ctx.op_buf_ion_info) {
   4916           DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   4917           return OMX_ErrorInsufficientResources;
   4918       }
   4919 #endif
   4920 
   4921     if(m_out_mem_ptr /*&& pPtr*/ && drv_ctx.ptr_outputbuffer
   4922        && drv_ctx.ptr_respbuffer)
   4923     {
   4924       drv_ctx.ptr_outputbuffer[0].mmaped_size =
   4925         (drv_ctx.op_buf.buffer_size *
   4926          drv_ctx.op_buf.actualcount);
   4927       bufHdr          =  m_out_mem_ptr;
   4928 
   4929       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   4930 
   4931       for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
   4932       {
   4933         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   4934         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   4935         // Set the values when we determine the right HxW param
   4936         bufHdr->nAllocLen          = bytes;
   4937         bufHdr->nFilledLen         = 0;
   4938         bufHdr->pAppPrivate        = appData;
   4939         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   4940         bufHdr->pBuffer            = NULL;
   4941         bufHdr->nOffset            = 0;
   4942 
   4943         drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   4944 #ifdef USE_ION
   4945         drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
   4946         drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
   4947         drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
   4948 #endif
   4949 
   4950         /*Create a mapping between buffers*/
   4951         bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   4952         drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   4953                                             &drv_ctx.ptr_outputbuffer[i];
   4954         drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
   4955         drv_ctx.ptr_outputbuffer[i].bufferaddr =
   4956           pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
   4957 
   4958         DEBUG_PRINT_LOW(" pmem_fd = %d offset = %d address = %p",
   4959           pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
   4960           drv_ctx.ptr_outputbuffer[i].bufferaddr);
   4961         // Move the buffer and buffer header pointers
   4962         bufHdr++;
   4963 
   4964       }
   4965     }
   4966     else
   4967     {
   4968       if(m_out_mem_ptr)
   4969       {
   4970         free(m_out_mem_ptr);
   4971         m_out_mem_ptr = NULL;
   4972       }
   4973 
   4974       if(drv_ctx.ptr_outputbuffer)
   4975       {
   4976         free(drv_ctx.ptr_outputbuffer);
   4977         drv_ctx.ptr_outputbuffer = NULL;
   4978       }
   4979       if(drv_ctx.ptr_respbuffer)
   4980       {
   4981         free(drv_ctx.ptr_respbuffer);
   4982         drv_ctx.ptr_respbuffer = NULL;
   4983       }
   4984 #ifdef USE_ION
   4985     if (drv_ctx.op_buf_ion_info) {
   4986         DEBUG_PRINT_LOW(" Free o/p ion context");
   4987 	free(drv_ctx.op_buf_ion_info);
   4988         drv_ctx.op_buf_ion_info = NULL;
   4989     }
   4990 #endif
   4991       eRet =  OMX_ErrorInsufficientResources;
   4992     }
   4993   }
   4994 
   4995   for(i=0; i< drv_ctx.op_buf.actualcount; i++)
   4996   {
   4997     if(BITMASK_ABSENT(&m_out_bm_count,i))
   4998     {
   4999       DEBUG_PRINT_LOW(" Found a Free Output Buffer %d",i);
   5000       break;
   5001     }
   5002   }
   5003 
   5004   if (eRet == OMX_ErrorNone)
   5005   {
   5006     if(i < drv_ctx.op_buf.actualcount)
   5007     {
   5008       struct v4l2_buffer buf;
   5009       struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5010       int rc;
   5011 
   5012       drv_ctx.ptr_outputbuffer[i].buffer_len =
   5013         drv_ctx.op_buf.buffer_size;
   5014 
   5015     *bufferHdr = (m_out_mem_ptr + i );
   5016     drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   5017 
   5018 #ifndef STUB_VPU
   5019 	  if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   5020 		enum v4l2_buf_type buf_type;
   5021 		buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5022 		rc=ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMON,&buf_type);
   5023 		if (rc) {
   5024 			DEBUG_PRINT_ERROR("allocate_output_buffer STREAMON failed \n ");
   5025 			return OMX_ErrorInsufficientResources;
   5026 		} else {
   5027 			streaming[CAPTURE_PORT] = true;
   5028 			DEBUG_PRINT_HIGH("allocate_output_buffer STREAMON Successful \n ");
   5029 		}
   5030 	  }
   5031 #endif
   5032 
   5033       (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   5034       (*bufferHdr)->pAppPrivate = appData;
   5035       BITMASK_SET(&m_out_bm_count,i);
   5036     }
   5037     else
   5038     {
   5039       DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
   5040       eRet = OMX_ErrorInsufficientResources;
   5041     }
   5042   }
   5043 
   5044   return eRet;
   5045 }
   5046 
   5047 
   5048 // AllocateBuffer  -- API Call
   5049 /* ======================================================================
   5050 FUNCTION
   5051   omx_vdpp::AllocateBuffer
   5052 
   5053 DESCRIPTION
   5054   Returns zero if all the buffers released..
   5055 
   5056 PARAMETERS
   5057   None.
   5058 
   5059 RETURN VALUE
   5060   true/false
   5061 
   5062 ========================================================================== */
   5063 OMX_ERRORTYPE  omx_vdpp::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   5064                                      OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5065                                      OMX_IN OMX_U32                        port,
   5066                                      OMX_IN OMX_PTR                     appData,
   5067                                      OMX_IN OMX_U32                       bytes)
   5068 {
   5069     unsigned i = 0;
   5070     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   5071 
   5072     DEBUG_PRINT_LOW(" Allocate buffer on port %d \n", (int)port);
   5073     if(m_state == OMX_StateInvalid)
   5074     {
   5075         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
   5076         return OMX_ErrorInvalidState;
   5077     }
   5078 
   5079     if(port == OMX_CORE_INPUT_PORT_INDEX)
   5080     {
   5081         eRet = allocate_input_heap_buffer(hComp,bufferHdr,port,appData,bytes);
   5082     }
   5083     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   5084     {
   5085         eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   5086     }
   5087     else
   5088     {
   5089       DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   5090       eRet = OMX_ErrorBadPortIndex;
   5091     }
   5092     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   5093     if(eRet == OMX_ErrorNone)
   5094     {
   5095         if(allocate_done()){
   5096             if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   5097             {
   5098                 // Send the callback now
   5099                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   5100                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   5101                                    OMX_COMPONENT_GENERATE_EVENT);
   5102             }
   5103         }
   5104         if(port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated)
   5105         {
   5106           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
   5107           {
   5108              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5109              post_event(OMX_CommandPortEnable,
   5110                         OMX_CORE_INPUT_PORT_INDEX,
   5111                         OMX_COMPONENT_GENERATE_EVENT);
   5112           }
   5113         }
   5114         if(port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated)
   5115             {
   5116           if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
   5117           {
   5118              BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5119                 post_event(OMX_CommandPortEnable,
   5120                            OMX_CORE_OUTPUT_PORT_INDEX,
   5121                            OMX_COMPONENT_GENERATE_EVENT);
   5122             }
   5123         }
   5124     }
   5125     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
   5126     return eRet;
   5127 }
   5128 
   5129 // Free Buffer - API call
   5130 /* ======================================================================
   5131 FUNCTION
   5132   omx_vdpp::FreeBuffer
   5133 
   5134 DESCRIPTION
   5135 
   5136 PARAMETERS
   5137   None.
   5138 
   5139 RETURN VALUE
   5140   true/false
   5141 
   5142 ========================================================================== */
   5143 OMX_ERRORTYPE  omx_vdpp::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   5144                                       OMX_IN OMX_U32                 port,
   5145                                       OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5146 {
   5147     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5148     unsigned int nPortIndex;
   5149     DEBUG_PRINT_LOW("In for vdpp free_buffer \n");
   5150 
   5151     if(m_state == OMX_StateIdle &&
   5152        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   5153     {
   5154         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
   5155     }
   5156     else if((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   5157             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX))
   5158     {
   5159         DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
   5160     }
   5161     else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
   5162     {
   5163         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
   5164         post_event(OMX_EventError,
   5165                    OMX_ErrorPortUnpopulated,
   5166                    OMX_COMPONENT_GENERATE_EVENT);
   5167 
   5168         return OMX_ErrorIncorrectStateOperation;
   5169     }
   5170     else if (m_state != OMX_StateInvalid)
   5171     {
   5172         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
   5173         post_event(OMX_EventError,
   5174                    OMX_ErrorPortUnpopulated,
   5175                    OMX_COMPONENT_GENERATE_EVENT);
   5176     }
   5177 
   5178     if(port == OMX_CORE_INPUT_PORT_INDEX)
   5179     {
   5180       /*Check if arbitrary bytes*/
   5181       if(!input_use_buffer)
   5182         nPortIndex = buffer - m_inp_mem_ptr;
   5183       else
   5184         nPortIndex = buffer - m_inp_heap_ptr;
   5185 
   5186         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
   5187         if(nPortIndex < drv_ctx.ip_buf.actualcount)
   5188         {
   5189          // Clear the bit associated with it.
   5190          BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   5191          BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   5192          if (input_use_buffer == true)
   5193          {
   5194 
   5195             DEBUG_PRINT_LOW(" Free pmem Buffer index %d",nPortIndex);
   5196             if(m_phdr_pmem_ptr)
   5197               free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   5198          }
   5199          else
   5200          {
   5201              free_input_buffer(buffer);
   5202          }
   5203          m_inp_bPopulated = OMX_FALSE;
   5204          /*Free the Buffer Header*/
   5205           if (release_input_done())
   5206           {
   5207             DEBUG_PRINT_HIGH(" ALL input buffers are freed/released");
   5208             free_input_buffer_header();
   5209           }
   5210         }
   5211         else
   5212         {
   5213             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
   5214             eRet = OMX_ErrorBadPortIndex;
   5215         }
   5216 
   5217         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   5218            && release_input_done())
   5219         {
   5220             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   5221             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   5222             post_event(OMX_CommandPortDisable,
   5223                        OMX_CORE_INPUT_PORT_INDEX,
   5224                        OMX_COMPONENT_GENERATE_EVENT);
   5225         }
   5226     }
   5227     else if(port == OMX_CORE_OUTPUT_PORT_INDEX)
   5228     {
   5229         // check if the buffer is valid
   5230         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
   5231         if(nPortIndex < drv_ctx.op_buf.actualcount)
   5232         {
   5233             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
   5234             // Clear the bit associated with it.
   5235             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   5236             m_out_bPopulated = OMX_FALSE;
   5237             free_output_buffer (buffer);
   5238 
   5239             if (release_output_done())
   5240             {
   5241               free_output_buffer_header();
   5242             }
   5243         }
   5244         else
   5245         {
   5246             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
   5247             eRet = OMX_ErrorBadPortIndex;
   5248         }
   5249         if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   5250            && release_output_done())
   5251         {
   5252             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
   5253 
   5254                 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   5255                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   5256 #ifdef _ANDROID_ICS_
   5257                 if (m_enable_android_native_buffers)
   5258                 {
   5259                     DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   5260                     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   5261                 }
   5262 #endif
   5263 
   5264                 post_event(OMX_CommandPortDisable,
   5265                            OMX_CORE_OUTPUT_PORT_INDEX,
   5266                            OMX_COMPONENT_GENERATE_EVENT);
   5267         }
   5268     }
   5269     else
   5270     {
   5271         eRet = OMX_ErrorBadPortIndex;
   5272     }
   5273     if((eRet == OMX_ErrorNone) &&
   5274        (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
   5275     {
   5276         if(release_done())
   5277         {
   5278             // Send the callback now
   5279             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   5280             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   5281                                       OMX_COMPONENT_GENERATE_EVENT);
   5282         }
   5283     }
   5284     return eRet;
   5285 }
   5286 
   5287 
   5288 /* ======================================================================
   5289 FUNCTION
   5290   omx_vdpp::EmptyThisBuffer
   5291 
   5292 DESCRIPTION
   5293   This routine is used to push the video frames to VDPP.
   5294 
   5295 PARAMETERS
   5296   None.
   5297 
   5298 RETURN VALUE
   5299   OMX Error None if everything went successful.
   5300 
   5301 ========================================================================== */
   5302 OMX_ERRORTYPE  omx_vdpp::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   5303                                            OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5304 {
   5305   OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   5306   unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   5307 
   5308   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer buffer = %p, buffer->pBuffer = %p, buffer->pPlatformPrivate = %p, buffer->nFilledLen = %lu\n",
   5309   //    buffer, buffer->pBuffer, buffer->pPlatformPrivate, buffer->nFilledLen);
   5310   if(m_state == OMX_StateInvalid)
   5311   {
   5312       DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
   5313       return OMX_ErrorInvalidState;
   5314   }
   5315 
   5316   if (buffer == NULL)
   5317   {
   5318     DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   5319     return OMX_ErrorBadParameter;
   5320   }
   5321 
   5322   if (!m_inp_bEnabled)
   5323   {
   5324     DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   5325     return OMX_ErrorIncorrectStateOperation;
   5326   }
   5327 
   5328   if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX)
   5329   {
   5330     DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
   5331     return OMX_ErrorBadPortIndex;
   5332   }
   5333 
   5334   if (input_use_buffer == true)
   5335   {
   5336        nBufferIndex = buffer - m_inp_heap_ptr;
   5337        m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   5338        m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   5339        m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   5340        buffer = &m_inp_mem_ptr[nBufferIndex]; //  change heap buffer address to ION buffer address
   5341        //DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem %p in Index %d, buffer %p of size %lu",
   5342        //                  &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
   5343   }
   5344   else{
   5345        nBufferIndex = buffer - m_inp_mem_ptr;
   5346   }
   5347 
   5348   if (nBufferIndex > drv_ctx.ip_buf.actualcount )
   5349   {
   5350     DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   5351     return OMX_ErrorBadParameter;
   5352   }
   5353 
   5354   DEBUG_PRINT_HIGH("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
   5355     buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
   5356 
   5357   set_frame_rate(buffer->nTimeStamp);
   5358   post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
   5359 
   5360   return OMX_ErrorNone;
   5361 }
   5362 
   5363 /* ======================================================================
   5364 FUNCTION
   5365   omx_vdpp::empty_this_buffer_proxy
   5366 
   5367 DESCRIPTION
   5368   This routine is used to push the video decoder output frames to
   5369   the VDPP.
   5370 
   5371 PARAMETERS
   5372   None.
   5373 
   5374 RETURN VALUE
   5375   OMX Error None if everything went successful.
   5376 
   5377 ========================================================================== */
   5378 OMX_ERRORTYPE  omx_vdpp::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
   5379                                                  OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5380 {
   5381   int i=0;
   5382   unsigned nPortIndex = 0;
   5383   OMX_ERRORTYPE ret = OMX_ErrorNone;
   5384   struct vdpp_bufferpayload *temp_buffer;
   5385   unsigned p1 = 0;
   5386   unsigned p2 = 0;
   5387 
   5388   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 1\n");
   5389   /*Should we generate a Aync error event*/
   5390   if (buffer == NULL || buffer->pInputPortPrivate == NULL)
   5391   {
   5392     DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   5393     return OMX_ErrorBadParameter;
   5394   }
   5395 
   5396   nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   5397   DEBUG_PRINT_HIGH("omx_vdpp::empty_this_buffer_proxy 2 nPortIndex = %d, buffer->nFilledLen = %lu\n", nPortIndex, buffer->nFilledLen);
   5398   if (nPortIndex > drv_ctx.ip_buf.actualcount)
   5399   {
   5400     DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   5401         nPortIndex);
   5402     return OMX_ErrorBadParameter;
   5403   }
   5404 
   5405   pending_input_buffers++;
   5406   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 pending_input_buffers = %d\n", pending_input_buffers);
   5407   /* return zero length and not an EOS buffer */
   5408   if ((buffer->nFilledLen == 0) &&
   5409      ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))
   5410   {
   5411     DEBUG_PRINT_HIGH(" return zero legth buffer");
   5412     post_event ((unsigned int)buffer,VDPP_S_SUCCESS,
   5413                      OMX_COMPONENT_GENERATE_EBD);
   5414     return OMX_ErrorNone;
   5415   }
   5416 
   5417   // check OMX_BUFFERFLAG_EXTRADATA for interlaced information
   5418   // and set it to drv_ctx.interlace if returned interlace mode
   5419   // doesn't match drv_ctx.interlace.
   5420   DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 buffer->nFlags = 0x%x interlace_user_flag = %d ", buffer->nFlags, interlace_user_flag);
   5421   if(((buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) != 0) && (false == interlace_user_flag))
   5422   {
   5423       OMX_OTHER_EXTRADATATYPE *pExtra;
   5424       v4l2_field field = drv_ctx.interlace;// V4L2_FIELD_NONE;
   5425       OMX_U8 *pTmp = buffer->pBuffer + buffer->nOffset + 3;
   5426 
   5427       pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U32) pTmp) & ~3);
   5428       DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 3 buffer->nFlags = 0x%x, pExtra->eType = 0x%x\n", buffer->nFlags, pExtra->eType);
   5429       // traverset the list of extra data sections
   5430       while(OMX_ExtraDataNone != pExtra->eType)
   5431       {
   5432           if(OMX_ExtraDataInterlaceFormat == (OMX_QCOM_EXTRADATATYPE)pExtra->eType)
   5433           {
   5434               OMX_STREAMINTERLACEFORMAT *interlace_format;
   5435               interlace_format = (OMX_STREAMINTERLACEFORMAT *)pExtra->data;
   5436 
   5437               switch (interlace_format->nInterlaceFormats)
   5438               {
   5439                 case OMX_InterlaceFrameProgressive:
   5440                     {
   5441                         field = V4L2_FIELD_NONE;
   5442                         DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy  V4L2_FIELD_NONE");
   5443                         break;
   5444                     }
   5445                 case OMX_InterlaceInterleaveFrameTopFieldFirst:
   5446                     {
   5447                         field = V4L2_FIELD_INTERLACED_TB;
   5448                         DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy  V4L2_FIELD_INTERLACED_TB");
   5449                         break;
   5450                     }
   5451                 case OMX_InterlaceInterleaveFrameBottomFieldFirst:
   5452                     {
   5453                         field = V4L2_FIELD_INTERLACED_BT;
   5454                         DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy  V4L2_FIELD_INTERLACED_BT");
   5455                         break;
   5456                     }
   5457                 case OMX_InterlaceFrameTopFieldFirst:
   5458                     {
   5459                         field = V4L2_FIELD_SEQ_TB;
   5460                         break;
   5461                     }
   5462                 case OMX_InterlaceFrameBottomFieldFirst:
   5463                     {
   5464                         field = V4L2_FIELD_SEQ_BT;
   5465                         break;
   5466                     }
   5467                 default:
   5468                     break;
   5469               }
   5470             break;
   5471           }
   5472           pExtra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) pExtra) + pExtra->nSize);
   5473       }
   5474 
   5475       if(drv_ctx.interlace != field)
   5476       {
   5477           drv_ctx.interlace = field;
   5478 
   5479           // set input port format based on the detected interlace mode
   5480           ret = set_buffer_req(&drv_ctx.ip_buf);
   5481           if(OMX_ErrorNone != ret)
   5482           {
   5483              DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid format setting");
   5484              return ret;
   5485           }
   5486       }
   5487   }
   5488 
   5489   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 4 \n");
   5490   if(input_flush_progress == true)
   5491   {
   5492     DEBUG_PRINT_LOW(" Flush in progress return buffer ");
   5493     post_event ((unsigned int)buffer,VDPP_S_SUCCESS,
   5494                      OMX_COMPONENT_GENERATE_EBD);
   5495     return OMX_ErrorNone;
   5496   }
   5497 
   5498   temp_buffer = (struct vdpp_bufferpayload *)buffer->pInputPortPrivate;
   5499 
   5500   if ((temp_buffer -  drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount)
   5501   {
   5502     return OMX_ErrorBadParameter;
   5503   }
   5504 
   5505   //DEBUG_PRINT_LOW(" ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   5506   /*for use_input_heap_buffer memcpy is used*/
   5507   temp_buffer->buffer_len = buffer->nFilledLen;
   5508 
   5509 
   5510   if (input_use_buffer)
   5511   {
   5512     //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5 \n");
   5513     if (buffer->nFilledLen <= temp_buffer->buffer_len)
   5514     {
   5515         DEBUG_PRINT_HIGH("omx_vdpp::empty_this_buffer_proxy 5.1 temp_buffer->bufferaddr = %p, m_inp_heap_ptr[%d].pPlatformPrivate = %p, m_inp_heap_ptr[%d].nOffset = %lu\n",
   5516             temp_buffer->bufferaddr, nPortIndex, m_inp_heap_ptr[nPortIndex].pPlatformPrivate, nPortIndex, m_inp_heap_ptr[nPortIndex].nOffset);
   5517         //memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pPlatformPrivate + m_inp_heap_ptr[nPortIndex].nOffset),
   5518         //        buffer->nFilledLen);
   5519     }
   5520     else
   5521     {
   5522       return OMX_ErrorBadParameter;
   5523     }
   5524     //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.2 \n");
   5525   }
   5526 
   5527 #ifdef INPUT_BUFFER_LOG
   5528     if ((inputBufferFile >= 0) && (input_buffer_write_counter < 10))
   5529     {
   5530         int stride = drv_ctx.video_resolution_input.stride; //w
   5531         int scanlines = drv_ctx.video_resolution_input.scan_lines; //h
   5532         DEBUG_PRINT_HIGH("omx_vdpp::empty_buffer_done 2.5 stride = %d, scanlines = %d , frame_height = %d", stride, scanlines, drv_ctx.video_resolution_input.frame_height);
   5533         char *temp = (char *)temp_buffer->bufferaddr;
   5534 	    unsigned i;
   5535 	    int bytes_written = 0;
   5536 	    for (i = 0; i < drv_ctx.video_resolution_input.frame_height; i++) {
   5537 		    bytes_written = write(inputBufferFile, temp, drv_ctx.video_resolution_input.frame_width);
   5538 		    temp += stride;
   5539 	    }
   5540 	    temp = (char *)(char *)temp_buffer->bufferaddr + stride * scanlines;
   5541         int stride_c = stride;
   5542 	    for(i = 0; i < drv_ctx.video_resolution_input.frame_height/2; i++) {
   5543 		    bytes_written += write(inputBufferFile, temp, drv_ctx.video_resolution_input.frame_width);
   5544 		    temp += stride_c;
   5545 	    }
   5546         input_buffer_write_counter++;
   5547     }
   5548 
   5549     if(input_buffer_write_counter >= 10 )
   5550     {
   5551         close(inputBufferFile);
   5552     }
   5553 #endif
   5554 
   5555   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.3 \n");
   5556   if(buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ)
   5557   {
   5558      //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 5.4 \n");
   5559     buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   5560   }
   5561 
   5562     struct v4l2_buffer buf;
   5563     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5564     int extra_idx = 0;
   5565     int rc;
   5566     unsigned long  print_count;
   5567 
   5568     memset( (void *)&buf, 0, sizeof(buf));
   5569     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   5570 
   5571     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS))
   5572     {  buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   5573         DEBUG_PRINT_HIGH("temp_buffer->buffer_len = %d, buffer->nFlags = 0x%lx \n", temp_buffer->buffer_len, buffer->nFlags) ;
   5574         DEBUG_PRINT_HIGH("  INPUT EOS reached \n") ;
   5575     }
   5576 
   5577 	OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5578 
   5579     // The following fills v4l2_buffer structure
   5580 	buf.index = nPortIndex;
   5581 	buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5582     buf.field = drv_ctx.interlace;
   5583 	buf.memory = V4L2_MEMORY_USERPTR;
   5584 	buf.length = drv_ctx.input_num_planes;
   5585 
   5586     // currently V4L2 driver just passes timestamp to maple FW, and maple FW
   5587     // pass the timestamp back to OMX
   5588     *(uint64_t *)(&buf.timestamp) = buffer->nTimeStamp;
   5589 
   5590     plane[0].bytesused = drv_ctx.video_resolution_input.frame_width *
   5591                          drv_ctx.video_resolution_input.frame_height *
   5592                          drv_ctx.input_bytesperpixel[0];//buffer->nFilledLen = 0 at this stage
   5593     plane[0].length = paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
   5594                       drv_ctx.video_resolution_input.frame_height *
   5595                       drv_ctx.input_bytesperpixel[0];
   5596     plane[0].m.userptr = temp_buffer->pmem_fd;
   5597     plane[0].reserved[0] = 0;
   5598     extra_idx = EXTRADATA_IDX(drv_ctx.input_num_planes);
   5599     if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
   5600     plane[extra_idx].bytesused = drv_ctx.video_resolution_input.frame_width *
   5601                                  drv_ctx.video_resolution_input.frame_height *
   5602                                  drv_ctx.input_bytesperpixel[extra_idx];
   5603     plane[extra_idx].length = paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
   5604                               drv_ctx.video_resolution_input.frame_height *
   5605                               drv_ctx.input_bytesperpixel[extra_idx];
   5606 
   5607 
   5608     plane[extra_idx].m.userptr = temp_buffer->pmem_fd;
   5609     plane[extra_idx].reserved[0] = plane[0].reserved[0] + drv_ctx.video_resolution_input.stride * drv_ctx.video_resolution_input.scan_lines;
   5610     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   5611     DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
   5612     return OMX_ErrorBadParameter;
   5613     }
   5614     buf.m.planes = plane;
   5615     buf.length = drv_ctx.input_num_planes;
   5616     /*DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy: buffer->nFilledLen = %d, plane[0].bytesused = %d  plane[0].length = %d,\
   5617                     plane[extra_idx].bytesused = %d, plane[extra_idx].length = %d, plane[extra_idx].data_offset = %d plane[0].data_offset = %d\
   5618                     buf.timestamp.tv_sec = 0x%08x, buf.timestamp.tv_usec = 0x%08x\n",
   5619                     buffer->nFilledLen, plane[0].bytesused, plane[0].length, plane[extra_idx].bytesused, plane[extra_idx].length, plane[extra_idx].data_offset, plane[0].data_offset,
   5620                     buf.timestamp.tv_sec, buf.timestamp.tv_usec);
   5621     DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy: buffer->nTimeStamp = 0x%016llx; buf.timestamp.tv_sec = 0x%08lx, buf.timestamp.tv_usec = 0x%08lx\n",
   5622                    buffer->nTimeStamp, buf.timestamp.tv_sec, buf.timestamp.tv_usec);*/
   5623 
   5624     input_qbuf_count++;
   5625 
   5626 #ifdef STUB_VPU
   5627 
   5628 #else
   5629 	rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QBUF, &buf);
   5630 	if(rc)
   5631 	{
   5632 		DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
   5633 		return OMX_ErrorHardware;
   5634 	}
   5635 #endif
   5636 
   5637   //DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 15 \n");
   5638 #ifndef STUB_VPU
   5639   if(!streaming[OUTPUT_PORT])
   5640   {
   5641 	enum v4l2_buf_type buf_type;
   5642 	int ret,r;
   5643     DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 16 \n");
   5644 	buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5645         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   5646 	ret=ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMON,&buf_type);
   5647 	if(!ret) {
   5648 		DEBUG_PRINT_HIGH("V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE STREAMON Successful \n");
   5649 		streaming[OUTPUT_PORT] = true;
   5650 	} else{
   5651 		DEBUG_PRINT_ERROR(" \n Failed to call streamon on V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE \n");
   5652         return OMX_ErrorInsufficientResources;
   5653 	}
   5654 }
   5655 #endif
   5656 
   5657 #ifdef STUB_VPU
   5658   drv_ctx.etb_ftb_info.etb_cnt++;
   5659   DEBUG_PRINT_LOW("omx_vdpp::empty_this_buffer_proxy 15 drv_ctx.etb_ftb_info.etb_cnt = %d\n", drv_ctx.etb_ftb_info.etb_cnt);
   5660   m_index_q_etb.insert_entry(p1,p2,nPortIndex);
   5661   //drv_ctx.etb_ftb_info.etb_index = nPortIndex;
   5662   drv_ctx.etb_ftb_info.etb_len = buf.length;
   5663   sem_post (&(drv_ctx.async_lock));
   5664 #endif
   5665   return ret;
   5666 }
   5667 
   5668 /* ======================================================================
   5669 FUNCTION
   5670   omx_vdpp::FillThisBuffer
   5671 
   5672 DESCRIPTION
   5673   IL client uses this method to release the frame buffer
   5674   after displaying them.
   5675 
   5676 PARAMETERS
   5677   None.
   5678 
   5679 RETURN VALUE
   5680   true/false
   5681 
   5682 ========================================================================== */
   5683 OMX_ERRORTYPE  omx_vdpp::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   5684                                           OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5685 {
   5686 
   5687   if(m_state == OMX_StateInvalid)
   5688   {
   5689       DEBUG_PRINT_ERROR("FTB in Invalid State\n");
   5690       return OMX_ErrorInvalidState;
   5691   }
   5692 
   5693   if (!m_out_bEnabled)
   5694   {
   5695     DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   5696     return OMX_ErrorIncorrectStateOperation;
   5697   }
   5698 
   5699   if (buffer == NULL ||
   5700       ((buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount))
   5701   {
   5702     return OMX_ErrorBadParameter;
   5703   }
   5704 
   5705   if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX)
   5706   {
   5707     DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
   5708     return OMX_ErrorBadPortIndex;
   5709   }
   5710   //DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu", buffer, buffer->pBuffer, buffer->nFilledLen);
   5711   post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
   5712 
   5713   return OMX_ErrorNone;
   5714 }
   5715 /* ======================================================================
   5716 FUNCTION
   5717   omx_vdpp::fill_this_buffer_proxy
   5718 
   5719 DESCRIPTION
   5720   IL client uses this method to release the frame buffer
   5721   after displaying them.
   5722 
   5723 PARAMETERS
   5724   None.
   5725 
   5726 RETURN VALUE
   5727   true/false
   5728 
   5729 ========================================================================== */
   5730 OMX_ERRORTYPE  omx_vdpp::fill_this_buffer_proxy(
   5731                          OMX_IN OMX_HANDLETYPE        hComp,
   5732                          OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   5733 {
   5734   OMX_ERRORTYPE nRet = OMX_ErrorNone;
   5735   OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   5736   unsigned nPortIndex = 0;
   5737   struct vdpp_bufferpayload     *ptr_outputbuffer = NULL;
   5738   struct vdpp_output_frameinfo  *ptr_respbuffer = NULL;
   5739   private_handle_t *handle = NULL;
   5740 
   5741   unsigned p1 = 0;
   5742   unsigned p2 = 0;
   5743 
   5744   nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_out_mem_ptr);
   5745 
   5746   if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
   5747     return OMX_ErrorBadParameter;
   5748 
   5749   DEBUG_PRINT_HIGH(" FTBProxy: nPortIndex = %d, bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu",
   5750       nPortIndex, bufferAdd, bufferAdd->pBuffer, buffer->nFilledLen);
   5751 
   5752       /*Return back the output buffer to client*/
   5753   if(m_out_bEnabled != OMX_TRUE || output_flush_progress == true)
   5754   {
   5755     DEBUG_PRINT_LOW(" Output Buffers return flush/disable condition");
   5756     buffer->nFilledLen = 0;
   5757     m_cb.FillBufferDone (hComp,m_app_data,buffer);
   5758     return OMX_ErrorNone;
   5759   }
   5760   pending_output_buffers++;
   5761 
   5762   // set from allocate_output_headers
   5763   ptr_respbuffer = (struct vdpp_output_frameinfo*)buffer->pOutputPortPrivate;
   5764   if (ptr_respbuffer)
   5765   {
   5766     ptr_outputbuffer =  (struct vdpp_bufferpayload*)ptr_respbuffer->client_data;
   5767   }
   5768 
   5769   if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL)
   5770   {
   5771       DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   5772       buffer->nFilledLen = 0;
   5773       m_cb.FillBufferDone (hComp,m_app_data,buffer);
   5774       pending_output_buffers--;
   5775       return OMX_ErrorBadParameter;
   5776   }
   5777 
   5778   int rc = 0;
   5779   struct v4l2_buffer buf;
   5780   struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5781   int extra_idx = 0;
   5782   memset( (void *)&buf, 0, sizeof(buf));
   5783   memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   5784 
   5785   buf.index = nPortIndex;
   5786   buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5787   buf.memory = V4L2_MEMORY_USERPTR;
   5788   buf.field = V4L2_FIELD_ANY;
   5789 
   5790   buf.length = drv_ctx.output_num_planes;
   5791   plane[0].bytesused = drv_ctx.video_resolution_output.frame_width *
   5792                        drv_ctx.video_resolution_output.frame_height *
   5793                        drv_ctx.output_bytesperpixel[0];
   5794   plane[0].length = paddedFrameWidth128(drv_ctx.video_resolution_output.frame_width) *
   5795                        drv_ctx.video_resolution_output.frame_height *
   5796                        drv_ctx.output_bytesperpixel[0];
   5797 
   5798   plane[0].m.userptr = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   5799   plane[0].reserved[0] = 0;
   5800   extra_idx = EXTRADATA_IDX(drv_ctx.output_num_planes);
   5801   if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
   5802     plane[extra_idx].bytesused = drv_ctx.video_resolution_output.frame_width *
   5803                                     drv_ctx.video_resolution_output.frame_height *
   5804                                     drv_ctx.output_bytesperpixel[extra_idx];
   5805     plane[extra_idx].length = paddedFrameWidth128(drv_ctx.video_resolution_output.frame_width) *
   5806                                 drv_ctx.video_resolution_output.frame_height *
   5807                                 drv_ctx.output_bytesperpixel[extra_idx];
   5808     plane[extra_idx].m.userptr = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   5809     plane[extra_idx].reserved[0] = plane[0].reserved[0] + drv_ctx.video_resolution_output.stride * drv_ctx.video_resolution_output.scan_lines;// plane[0].length;
   5810     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   5811     DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
   5812     return OMX_ErrorBadParameter;
   5813     }
   5814   buf.m.planes = plane;
   5815   // DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy: buffer->nFilledLen = %lu, plane[0].bytesused = %d  plane[0].length = %d, \
   5816                     // plane[extra_idx].bytesused = %d, plane[extra_idx].reserved[0] = 0x%x\n", \
   5817                    // buffer->nFilledLen, plane[0].bytesused, plane[0].length, plane[extra_idx].bytesused, plane[extra_idx].reserved[0]);
   5818   //
   5819   //DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 2 drv_ctx.ptr_outputbuffer[%d].bufferaddr = %p\n", nPortIndex,drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr);
   5820   //DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 2 drv_ctx.ptr_outputbuffer[%d].offset = %d", nPortIndex,drv_ctx.ptr_outputbuffer[nPortIndex].offset);
   5821 
   5822 #ifdef STUB_VPU
   5823 
   5824 #else
   5825   rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_QBUF, &buf);
   5826   if (rc) {
   5827     DEBUG_PRINT_ERROR("Failed to qbuf to driver");
   5828     return OMX_ErrorHardware;
   5829   }
   5830 #endif
   5831 
   5832   output_qbuf_count++;
   5833   DEBUG_PRINT_LOW("omx_vdpp::fill_this_buffer_proxy 3\n");
   5834 #ifdef STUB_VPU
   5835 {
   5836   drv_ctx.etb_ftb_info.ftb_cnt++;
   5837   m_index_q_ftb.insert_entry(p1,p2,nPortIndex);
   5838   drv_ctx.etb_ftb_info.ftb_len = drv_ctx.op_buf.buffer_size;
   5839   sem_post (&(drv_ctx.async_lock));
   5840   DEBUG_PRINT_HIGH("omx_vdpp::fill_this_buffer_proxy 4 nPortIndex = %d, drv_ctx.etb_ftb_info.ftb_cnt = %d, drv_ctx.etb_ftb_info.ftb_len = %d\n",
   5841       nPortIndex, drv_ctx.etb_ftb_info.ftb_cnt, drv_ctx.etb_ftb_info.ftb_len);
   5842 }
   5843 #endif
   5844   return OMX_ErrorNone;
   5845 
   5846 }
   5847 
   5848 /* ======================================================================
   5849 FUNCTION
   5850   omx_vdpp::SetCallbacks
   5851 
   5852 DESCRIPTION
   5853   Set the callbacks.
   5854 
   5855 PARAMETERS
   5856   None.
   5857 
   5858 RETURN VALUE
   5859   OMX Error None if everything successful.
   5860 
   5861 ========================================================================== */
   5862 OMX_ERRORTYPE  omx_vdpp::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   5863                                            OMX_IN OMX_CALLBACKTYPE* callbacks,
   5864                                            OMX_IN OMX_PTR             appData)
   5865 {
   5866 
   5867   m_cb       = *callbacks;
   5868   DEBUG_PRINT_LOW(" Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   5869                m_cb.EventHandler,m_cb.FillBufferDone);
   5870   m_app_data =    appData;
   5871   return OMX_ErrorNotImplemented;
   5872 }
   5873 
   5874 /* ======================================================================
   5875 FUNCTION
   5876   omx_vdpp::ComponentDeInit
   5877 
   5878 DESCRIPTION
   5879   Destroys the component and release memory allocated to the heap.
   5880 
   5881 PARAMETERS
   5882   <TBD>.
   5883 
   5884 RETURN VALUE
   5885   OMX Error None if everything successful.
   5886 
   5887 ========================================================================== */
   5888 OMX_ERRORTYPE  omx_vdpp::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   5889 {
   5890     unsigned i = 0;
   5891     DEBUG_PRINT_HIGH(" omx_vdpp::component_deinit");
   5892     if (OMX_StateLoaded != m_state)
   5893     {
   5894         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
   5895                           m_state);
   5896         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   5897     }
   5898     else
   5899     {
   5900       DEBUG_PRINT_HIGH(" Playback Ended - PASSED");
   5901     }
   5902 
   5903     /*Check if the output buffers have to be cleaned up*/
   5904     if(m_out_mem_ptr)
   5905     {
   5906         DEBUG_PRINT_LOW("Freeing the Output Memory\n");
   5907         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ )
   5908         {
   5909           free_output_buffer (&m_out_mem_ptr[i]);
   5910         }
   5911     }
   5912 
   5913     /*Check if the input buffers have to be cleaned up*/
   5914     if(m_inp_mem_ptr || m_inp_heap_ptr)
   5915     {
   5916         DEBUG_PRINT_LOW("Freeing the Input Memory\n");
   5917         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ )
   5918         {
   5919           if (m_inp_mem_ptr)
   5920             free_input_buffer (&m_inp_mem_ptr[i]);
   5921         }
   5922     }
   5923     free_input_buffer_header();
   5924     free_output_buffer_header();
   5925 
   5926     // Reset counters in mesg queues
   5927     m_ftb_q.m_size=0;
   5928     m_cmd_q.m_size=0;
   5929     m_etb_q.m_size=0;
   5930     m_index_q_ftb.m_size=0;
   5931     m_index_q_etb.m_size=0;
   5932     m_ftb_q.m_read = m_ftb_q.m_write =0;
   5933     m_cmd_q.m_read = m_cmd_q.m_write =0;
   5934     m_etb_q.m_read = m_etb_q.m_write =0;
   5935     m_index_q_ftb.m_read = m_index_q_ftb.m_write =0;
   5936     m_index_q_etb.m_read = m_index_q_etb.m_write =0;
   5937 #ifdef _ANDROID_
   5938     if (m_debug_timestamp)
   5939     {
   5940       m_timestamp_list.reset_ts_list();
   5941     }
   5942 #endif
   5943 
   5944     DEBUG_PRINT_HIGH(" Close the driver instance");
   5945 
   5946 #ifdef INPUT_BUFFER_LOG
   5947     if (inputBufferFile)
   5948       close (inputBufferFile);
   5949 #endif
   5950 #ifdef OUTPUT_BUFFER_LOG
   5951    if (outputBufferFile)
   5952      close(outputBufferFile);
   5953 #endif
   5954 #ifdef OUTPUT_EXTRADATA_LOG
   5955     if (outputExtradataFile)
   5956         fclose (outputExtradataFile);
   5957 #endif
   5958 
   5959   DEBUG_PRINT_HIGH(" omx_vdpp::component_deinit() complete");
   5960   return OMX_ErrorNone;
   5961 }
   5962 /* ======================================================================
   5963 FUNCTION
   5964   omx_vdpp::UseEGLImage
   5965 
   5966 DESCRIPTION
   5967   OMX Use EGL Image method implementation <TBD>.
   5968 
   5969 PARAMETERS
   5970   <TBD>.
   5971 
   5972 RETURN VALUE
   5973   Not Implemented error.
   5974 
   5975 ========================================================================== */
   5976 OMX_ERRORTYPE  omx_vdpp::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
   5977                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5978                                           OMX_IN OMX_U32                        port,
   5979                                           OMX_IN OMX_PTR                     appData,
   5980                                           OMX_IN void*                      eglImage)
   5981 {
   5982    return OMX_ErrorNone;
   5983 }
   5984 /* ======================================================================
   5985 FUNCTION
   5986   omx_vdpp::ComponentRoleEnum
   5987 
   5988 DESCRIPTION
   5989   OMX Component Role Enum method implementation.
   5990 
   5991 PARAMETERS
   5992   <TBD>.
   5993 
   5994 RETURN VALUE
   5995   OMX Error None if everything is successful.
   5996 ========================================================================== */
   5997 OMX_ERRORTYPE  omx_vdpp::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   5998                                                 OMX_OUT OMX_U8*        role,
   5999                                                 OMX_IN OMX_U32        index)
   6000 {
   6001   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6002 
   6003   // no component role (TODO add it later once component role is determined)
   6004 /*
   6005   if(!strncmp(drv_ctx.kind, "OMX.qcom.video.vidpp",OMX_MAX_STRINGNAME_SIZE))
   6006   {
   6007     if((0 == index) && role)
   6008     {
   6009       strlcpy((char *)role, "video.vidpp",OMX_MAX_STRINGNAME_SIZE);
   6010       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   6011     }
   6012     else
   6013     {
   6014       eRet = OMX_ErrorNoMore;
   6015     }
   6016   }
   6017 */
   6018   return eRet;
   6019 }
   6020 
   6021 
   6022 
   6023 
   6024 /* ======================================================================
   6025 FUNCTION
   6026   omx_vdpp::AllocateDone
   6027 
   6028 DESCRIPTION
   6029   Checks if entire buffer pool is allocated by IL Client or not.
   6030   Need this to move to IDLE state.
   6031 
   6032 PARAMETERS
   6033   None.
   6034 
   6035 RETURN VALUE
   6036   true/false.
   6037 
   6038 ========================================================================== */
   6039 bool omx_vdpp::allocate_done(void)
   6040 {
   6041   bool bRet = false;
   6042   bool bRet_In = false;
   6043   bool bRet_Out = false;
   6044 
   6045   //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 1\n");
   6046   bRet_In = allocate_input_done();
   6047   bRet_Out = allocate_output_done();
   6048 
   6049   if(bRet_In && bRet_Out)
   6050   {
   6051       bRet = true;
   6052   //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 2\n");
   6053   }
   6054     //DEBUG_PRINT_LOW("omx_vdpp::allocate_done 3\n");
   6055   return bRet;
   6056 }
   6057 /* ======================================================================
   6058 FUNCTION
   6059   omx_vdpp::AllocateInputDone
   6060 
   6061 DESCRIPTION
   6062   Checks if I/P buffer pool is allocated by IL Client or not.
   6063 
   6064 PARAMETERS
   6065   None.
   6066 
   6067 RETURN VALUE
   6068   true/false.
   6069 
   6070 ========================================================================== */
   6071 bool omx_vdpp::allocate_input_done(void)
   6072 {
   6073   bool bRet = false;
   6074   unsigned i=0;
   6075   //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 1\n");
   6076   if (m_inp_mem_ptr == NULL)
   6077   {
   6078   //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 2\n");
   6079       return bRet;
   6080   }
   6081   if(m_inp_mem_ptr )
   6082   {
   6083   //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 3\n");
   6084     for(;i<drv_ctx.ip_buf.actualcount;i++)
   6085     {
   6086       if(BITMASK_ABSENT(&m_inp_bm_count,i))
   6087       {
   6088         break;
   6089       }
   6090     }
   6091   }
   6092   //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 4 i = %d, drv_ctx.ip_buf.actualcount = %d\n", i, drv_ctx.ip_buf.actualcount);
   6093   if(i == drv_ctx.ip_buf.actualcount)
   6094   {
   6095     //DEBUG_PRINT_LOW("omx_vdpp::allocate_input_done 5\n");
   6096     bRet = true;
   6097     //DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   6098   }
   6099   if(i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled)
   6100   {
   6101      m_inp_bPopulated = OMX_TRUE;
   6102   }
   6103   return bRet;
   6104 }
   6105 /* ======================================================================
   6106 FUNCTION
   6107   omx_vdpp::AllocateOutputDone
   6108 
   6109 DESCRIPTION
   6110   Checks if entire O/P buffer pool is allocated by IL Client or not.
   6111 
   6112 PARAMETERS
   6113   None.
   6114 
   6115 RETURN VALUE
   6116   true/false.
   6117 
   6118 ========================================================================== */
   6119 bool omx_vdpp::allocate_output_done(void)
   6120 {
   6121   bool bRet = false;
   6122   unsigned j=0;
   6123 
   6124   if (m_out_mem_ptr == NULL)
   6125   {
   6126       return bRet;
   6127   }
   6128 
   6129   if (m_out_mem_ptr)
   6130   {
   6131     for(;j < drv_ctx.op_buf.actualcount;j++)
   6132     {
   6133       if(BITMASK_ABSENT(&m_out_bm_count,j))
   6134       {
   6135         break;
   6136       }
   6137     }
   6138   }
   6139 
   6140   if(j == drv_ctx.op_buf.actualcount)
   6141   {
   6142     bRet = true;
   6143     DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   6144     if(m_out_bEnabled)
   6145        m_out_bPopulated = OMX_TRUE;
   6146   }
   6147 
   6148   return bRet;
   6149 }
   6150 
   6151 /* ======================================================================
   6152 FUNCTION
   6153   omx_vdpp::ReleaseDone
   6154 
   6155 DESCRIPTION
   6156   Checks if IL client has released all the buffers.
   6157 
   6158 PARAMETERS
   6159   None.
   6160 
   6161 RETURN VALUE
   6162   true/false
   6163 
   6164 ========================================================================== */
   6165 bool omx_vdpp::release_done(void)
   6166 {
   6167   bool bRet = false;
   6168 
   6169   if(release_input_done())
   6170   {
   6171     if(release_output_done())
   6172     {
   6173         bRet = true;
   6174     }
   6175   }
   6176   return bRet;
   6177 }
   6178 
   6179 
   6180 /* ======================================================================
   6181 FUNCTION
   6182   omx_vdpp::ReleaseOutputDone
   6183 
   6184 DESCRIPTION
   6185   Checks if IL client has released all the buffers.
   6186 
   6187 PARAMETERS
   6188   None.
   6189 
   6190 RETURN VALUE
   6191   true/false
   6192 
   6193 ========================================================================== */
   6194 bool omx_vdpp::release_output_done(void)
   6195 {
   6196   bool bRet = false;
   6197   unsigned i=0,j=0;
   6198 
   6199   DEBUG_PRINT_LOW("omx_vdpp::release_output_done Value of m_out_mem_ptr %p",m_inp_mem_ptr);
   6200   if(m_out_mem_ptr)
   6201   {
   6202       for(;j < drv_ctx.op_buf.actualcount ; j++)
   6203       {
   6204         if(BITMASK_PRESENT(&m_out_bm_count,j))
   6205         {
   6206           break;
   6207         }
   6208       }
   6209     if(j == drv_ctx.op_buf.actualcount)
   6210     {
   6211       m_out_bm_count = 0;
   6212       bRet = true;
   6213     }
   6214   }
   6215   else
   6216   {
   6217     m_out_bm_count = 0;
   6218     bRet = true;
   6219   }
   6220   return bRet;
   6221 }
   6222 /* ======================================================================
   6223 FUNCTION
   6224   omx_vdpp::ReleaseInputDone
   6225 
   6226 DESCRIPTION
   6227   Checks if IL client has released all the buffers.
   6228 
   6229 PARAMETERS
   6230   None.
   6231 
   6232 RETURN VALUE
   6233   true/false
   6234 
   6235 ========================================================================== */
   6236 bool omx_vdpp::release_input_done(void)
   6237 {
   6238   bool bRet = false;
   6239   unsigned i=0,j=0;
   6240 
   6241   DEBUG_PRINT_LOW("omx_vdpp::release_input_done Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   6242   if(m_inp_mem_ptr)
   6243   {
   6244       for(;j<drv_ctx.ip_buf.actualcount;j++)
   6245       {
   6246         if( BITMASK_PRESENT(&m_inp_bm_count,j))
   6247         {
   6248           break;
   6249         }
   6250       }
   6251     if(j==drv_ctx.ip_buf.actualcount)
   6252     {
   6253       bRet = true;
   6254     }
   6255   }
   6256   else
   6257   {
   6258     bRet = true;
   6259   }
   6260   return bRet;
   6261 }
   6262 
   6263 OMX_ERRORTYPE omx_vdpp::fill_buffer_done(OMX_HANDLETYPE hComp,
   6264                                OMX_BUFFERHEADERTYPE * buffer)
   6265 {
   6266   OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   6267   //DEBUG_PRINT_LOW(" fill_buffer_done 1 : bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu",
   6268   //    buffer, buffer->pBuffer, buffer->nFilledLen);
   6269 
   6270   if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount)
   6271   {
   6272     DEBUG_PRINT_ERROR(" [FBD] ERROR in ptr(%p)", buffer);
   6273     return OMX_ErrorBadParameter;
   6274   }
   6275   else if (output_flush_progress)
   6276   {
   6277     DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   6278     buffer->nFilledLen = 0;
   6279     buffer->nTimeStamp = 0;
   6280     buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   6281     buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   6282     buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   6283   }
   6284 
   6285   DEBUG_PRINT_HIGH(" fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, buffer->nFilledLen = %lu, buffer->nFlags = 0x%x",
   6286       buffer, buffer->pBuffer, buffer->nFilledLen, buffer->nFlags);
   6287   pending_output_buffers --;
   6288   output_dqbuf_count++;
   6289   if (buffer->nFlags & OMX_BUFFERFLAG_EOS)
   6290   {
   6291     DEBUG_PRINT_HIGH(" Output EOS has been reached");
   6292     if (!output_flush_progress)
   6293       post_event((unsigned)NULL, (unsigned)NULL,
   6294               OMX_COMPONENT_GENERATE_EOS_DONE);
   6295 
   6296     if (psource_frame)
   6297     {
   6298       m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   6299       psource_frame = NULL;
   6300     }
   6301     if (pdest_frame)
   6302     {
   6303       pdest_frame->nFilledLen = 0;
   6304       m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
   6305               (unsigned)NULL);
   6306       pdest_frame = NULL;
   6307     }
   6308   }
   6309 
   6310   //DEBUG_PRINT_LOW(" In fill Buffer done call address %p , buffer->nFilledLen = %lu",buffer, buffer->nFilledLen);
   6311 #ifdef OUTPUT_BUFFER_LOG
   6312   DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 1.5, output_buffer_write_counter = %d", output_buffer_write_counter);
   6313     if(outputBufferFile < 0)
   6314     {
   6315 	  DEBUG_PRINT_ERROR(" Failed to create outputBufferFile \n");
   6316     }
   6317   if (outputBufferFile && buffer->nFilledLen && (output_buffer_write_counter <= 10))
   6318   {
   6319       DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 2");
   6320 	  int buf_index = buffer - m_out_mem_ptr;
   6321       int stride = drv_ctx.video_resolution_output.stride; //w
   6322       int scanlines = drv_ctx.video_resolution_output.scan_lines; //h
   6323       char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr; // mmap ION buffer addr
   6324 	  unsigned i;
   6325 	  int bytes_written = 0;
   6326 	  for (i = 0; i < drv_ctx.video_resolution_output.frame_height; i++) {
   6327 		  bytes_written = write(outputBufferFile, temp, drv_ctx.video_resolution_output.frame_width);
   6328 		  temp += stride;
   6329 	  }
   6330 	  temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   6331       int stride_c = stride;
   6332 	  for(i = 0; i < drv_ctx.video_resolution_output.frame_height/2; i++) {
   6333 		  bytes_written += write(outputBufferFile, temp, drv_ctx.video_resolution_output.frame_width);
   6334 		  temp += stride_c;
   6335 	  }
   6336       output_buffer_write_counter++;
   6337 
   6338       if(output_buffer_write_counter > 10)
   6339       {
   6340          close(outputBufferFile);
   6341          DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 2.9 close ");
   6342       }
   6343   }
   6344 #endif
   6345   //DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 3");
   6346 
   6347   if (m_cb.FillBufferDone)
   6348   {
   6349     //DEBUG_PRINT_LOW("omx_vdpp::fill_buffer_done 4");
   6350 
   6351     if (buffer->nFlags & OMX_BUFFERFLAG_EOS){
   6352       prev_ts = LLONG_MAX;
   6353       rst_prev_ts = true;
   6354       }
   6355 
   6356     DEBUG_PRINT_HIGH("omx_vdpp::fill_buffer_done 5 ");
   6357     m_cb.FillBufferDone (hComp,m_app_data, buffer);
   6358     DEBUG_PRINT_HIGH(" After Fill Buffer Done callback");
   6359 
   6360   }
   6361   else
   6362   {
   6363     return OMX_ErrorBadParameter;
   6364   }
   6365 
   6366   return OMX_ErrorNone;
   6367 }
   6368 
   6369 OMX_ERRORTYPE omx_vdpp::empty_buffer_done(OMX_HANDLETYPE         hComp,
   6370                                           OMX_BUFFERHEADERTYPE* buffer)
   6371 {
   6372     if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount))
   6373     {
   6374         DEBUG_PRINT_ERROR(" empty_buffer_done: ERROR bufhdr = %p", buffer);
   6375        return OMX_ErrorBadParameter;
   6376     }
   6377 
   6378     DEBUG_PRINT_LOW(" empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   6379         buffer, buffer->pBuffer);
   6380     pending_input_buffers--;
   6381     input_dqbuf_count++;
   6382 
   6383     if(m_cb.EmptyBufferDone)
   6384     {
   6385         buffer->nFilledLen = 0;
   6386         if (input_use_buffer == true){
   6387             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   6388         }
   6389         DEBUG_PRINT_HIGH("!!! empty_buffer_done before callback: buffer = %p\n", buffer);
   6390         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   6391     }
   6392     return OMX_ErrorNone;
   6393 }
   6394 
   6395 int omx_vdpp::async_message_process (void *context, void* message)
   6396 {
   6397   omx_vdpp* omx = NULL;
   6398   struct vdpp_msginfo *vdpp_msg = NULL;
   6399   OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   6400   struct v4l2_buffer *v4l2_buf_ptr = NULL;
   6401   struct vdpp_output_frameinfo *output_respbuf = NULL;
   6402   int rc=1;
   6403   //DEBUG_PRINT_LOW("async_message_process 0\n");
   6404   if (context == NULL || message == NULL)
   6405   {
   6406     DEBUG_PRINT_ERROR(" FATAL ERROR in omx_vdpp::async_message_process NULL Check");
   6407     return -1;
   6408   }
   6409   //DEBUG_PRINT_LOW("async_message_process 1\n");
   6410   vdpp_msg = (struct vdpp_msginfo *)message;
   6411 
   6412   omx = reinterpret_cast<omx_vdpp*>(context);
   6413 
   6414   switch (vdpp_msg->msgcode)
   6415   {
   6416 
   6417   case VDPP_MSG_EVT_HW_ERROR:
   6418     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6419                      OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   6420   break;
   6421 
   6422   case VDPP_MSG_RESP_START_DONE:
   6423     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6424                      OMX_COMPONENT_GENERATE_START_DONE);
   6425   break;
   6426 
   6427   case VDPP_MSG_RESP_STOP_DONE:
   6428     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6429                      OMX_COMPONENT_GENERATE_STOP_DONE);
   6430   break;
   6431 
   6432   case VDPP_MSG_RESP_RESUME_DONE:
   6433     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6434                      OMX_COMPONENT_GENERATE_RESUME_DONE);
   6435   break;
   6436 
   6437   case VDPP_MSG_RESP_PAUSE_DONE:
   6438     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6439                      OMX_COMPONENT_GENERATE_PAUSE_DONE);
   6440   break;
   6441 
   6442   case VDPP_MSG_RESP_FLUSH_INPUT_DONE:
   6443     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6444                      OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   6445     break;
   6446   case VDPP_MSG_RESP_FLUSH_OUTPUT_DONE:
   6447     omx->post_event ((unsigned)NULL, vdpp_msg->status_code,\
   6448                      OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   6449     break;
   6450   case VDPP_MSG_RESP_INPUT_FLUSHED:
   6451   case VDPP_MSG_RESP_INPUT_BUFFER_DONE:
   6452     //DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 0");
   6453     v4l2_buf_ptr = (v4l2_buffer*)vdpp_msg->msgdata.input_frame_clientdata;
   6454     // Use v4l2_buf_ptr->index returned by VPU V4L2 driver to index into
   6455     // m_inp_mem_ptr. v4l2 driver right now returns the same index used in QBUF
   6456     // In the future the returned ION handle could be used in empty_buffer_done.
   6457     omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
   6458     DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 1 v4l2_buf_ptr->index = %d", v4l2_buf_ptr->index);
   6459     if (omxhdr == NULL ||
   6460        ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) )
   6461     {
   6462        //DEBUG_PRINT_ERROR(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 2");
   6463        omxhdr = NULL;
   6464        vdpp_msg->status_code = VDPP_S_EFATAL;
   6465     }
   6466     //DEBUG_PRINT_LOW(" VDPP_MSG_RESP_INPUT_BUFFER_DONE 3");
   6467     // No need to update the omxhdr->nFilledLen using the plane[0].len + plane[1].len here.
   6468     // based on OMX 3.1.2.9.2, nFilledLen = 0 if input buffer is completely consumed in ebd.
   6469     // also refer to ebd code
   6470     omx->post_event ((unsigned int)omxhdr,vdpp_msg->status_code,
   6471                      OMX_COMPONENT_GENERATE_EBD);
   6472     break;
   6473   case VDPP_MSG_RESP_OUTPUT_FLUSHED:
   6474     case VDPP_MSG_RESP_OUTPUT_BUFFER_DONE:
   6475 
   6476       v4l2_buf_ptr = (v4l2_buffer*)vdpp_msg->msgdata.output_frame.client_data;
   6477       omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
   6478       DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 1 v4l2_buf_ptr->index = %d\n", v4l2_buf_ptr->index);
   6479 
   6480     if (omxhdr && omxhdr->pOutputPortPrivate &&
   6481         ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
   6482          (((struct vdpp_output_frameinfo *)omxhdr->pOutputPortPrivate
   6483             - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount))
   6484     {
   6485       if ( vdpp_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen)
   6486       {
   6487         //DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 2, vdpp_msg->msgdata.output_frame.len = %d, omxhdr->nAllocLen = %ld\n", vdpp_msg->msgdata.output_frame.len, omxhdr->nAllocLen);
   6488 	    omxhdr->nFilledLen = vdpp_msg->msgdata.output_frame.len;
   6489 	    omxhdr->nOffset = vdpp_msg->msgdata.output_frame.offset;
   6490         omxhdr->nTimeStamp = vdpp_msg->msgdata.output_frame.time_stamp;
   6491         omxhdr->nFlags = omx->m_out_mem_ptr[v4l2_buf_ptr->index].nFlags;
   6492 
   6493         //DEBUG_PRINT_LOW("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 2.5 omxhdr->nFilledLen = %ld\n", omxhdr->nFilledLen);
   6494 	    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)
   6495 	    {
   6496 	      omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   6497 	      //rc = -1;
   6498 	    }
   6499 
   6500       // use mmaped ION buffer address
   6501       vdpp_msg->msgdata.output_frame.bufferaddr =
   6502           omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   6503 
   6504         output_respbuf = (struct vdpp_output_frameinfo *)\
   6505                           omxhdr->pOutputPortPrivate;
   6506         output_respbuf->len = vdpp_msg->msgdata.output_frame.len;
   6507         output_respbuf->offset = vdpp_msg->msgdata.output_frame.offset;
   6508 
   6509         if (omx->output_use_buffer)
   6510           memcpy ( omxhdr->pBuffer, (void *)
   6511                    ((unsigned long)vdpp_msg->msgdata.output_frame.bufferaddr +
   6512                     (unsigned long)vdpp_msg->msgdata.output_frame.offset),
   6513                     vdpp_msg->msgdata.output_frame.len);
   6514       }
   6515       else
   6516         omxhdr->nFilledLen = 0;
   6517 
   6518       //DEBUG_PRINT_HIGH("VDPP_MSG_RESP_OUTPUT_BUFFER_DONE 4 omxhdr->nFilledLen = %ld, OMX_COMPONENT_GENERATE_FBD = %d\n", omxhdr->nFilledLen, OMX_COMPONENT_GENERATE_FBD);
   6519 
   6520       omx->post_event ((unsigned int)omxhdr, vdpp_msg->status_code,
   6521                        OMX_COMPONENT_GENERATE_FBD);
   6522     }
   6523     else if (vdpp_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
   6524       omx->post_event ((unsigned int)NULL, vdpp_msg->status_code,
   6525                        OMX_COMPONENT_GENERATE_EOS_DONE);
   6526     else
   6527       omx->post_event ((unsigned int)NULL, vdpp_msg->status_code,
   6528                        OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   6529     break;
   6530   case VDPP_MSG_EVT_CONFIG_CHANGED:
   6531     DEBUG_PRINT_HIGH(" Port settings changed");
   6532     omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   6533         OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   6534     break;
   6535   case VDPP_MSG_EVT_ACTIVE_REGION_DETECTION_STATUS:
   6536       {
   6537         struct v4l2_rect * p_ar_result = &(vdpp_msg->msgdata.ar_result);
   6538         DEBUG_PRINT_HIGH(" Active Region Detection Status");
   6539         omx->post_event ((unsigned int)p_ar_result,
   6540                           vdpp_msg->status_code,
   6541                           OMX_COMPONENT_GENERATE_ACTIVE_REGION_DETECTION_STATUS);
   6542         break;
   6543       }
   6544   default:
   6545     break;
   6546   }
   6547 
   6548 
   6549   return rc;
   6550 }
   6551 
   6552 #ifndef USE_ION
   6553 bool omx_vdpp::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   6554                                   OMX_U32 alignment)
   6555 {
   6556   struct pmem_allocation allocation;
   6557   allocation.size = buffer_size;
   6558   allocation.align = clip2(alignment);
   6559   if (allocation.align < 4096)
   6560   {
   6561     allocation.align = 4096;
   6562   }
   6563   if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0)
   6564   {
   6565     DEBUG_PRINT_ERROR(" Aligment(%u) failed with pmem driver Sz(%lu)",
   6566       allocation.align, allocation.size);
   6567     return false;
   6568   }
   6569   return true;
   6570 }
   6571 #endif
   6572 #ifdef USE_ION
   6573 int omx_vdpp::alloc_map_ion_memory(OMX_U32 buffer_size,
   6574               OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   6575 	      struct ion_fd_data *fd_data, int flag)
   6576 {
   6577   int fd = -EINVAL;
   6578   int rc = -EINVAL;
   6579   int ion_dev_flag;
   6580   struct vdpp_ion ion_buf_info;
   6581   if (!alloc_data || buffer_size <= 0 || !fd_data) {
   6582      DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
   6583      return -EINVAL;
   6584   }
   6585   ion_dev_flag = (O_RDONLY | O_DSYNC);
   6586   fd = open (MEM_DEVICE, ion_dev_flag);
   6587   if (fd < 0) {
   6588     DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
   6589     return fd;
   6590   }
   6591 
   6592   alloc_data->len = buffer_size;
   6593 
   6594   // the following settings are from vpu_test.c
   6595   alloc_data->align = 16;
   6596   alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   6597   alloc_data->flags = 0;
   6598 
   6599   rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   6600   if (rc || !alloc_data->handle) {
   6601     DEBUG_PRINT_ERROR(" ION ALLOC memory failed ");
   6602     alloc_data->handle = NULL;
   6603     close(fd);
   6604     fd = -ENOMEM;
   6605     return fd;
   6606   }
   6607   fd_data->handle = alloc_data->handle;
   6608   rc = ioctl(fd,ION_IOC_MAP,fd_data);
   6609   if (rc) {
   6610     DEBUG_PRINT_ERROR(" ION MAP failed ");
   6611     ion_buf_info.ion_alloc_data = *alloc_data;
   6612     ion_buf_info.ion_device_fd = fd;
   6613     ion_buf_info.fd_ion_data = *fd_data;
   6614     free_ion_memory(&ion_buf_info);
   6615     fd_data->fd =-1;
   6616     close(fd);
   6617     fd = -ENOMEM;
   6618   }
   6619 
   6620   return fd;
   6621 }
   6622 
   6623 void omx_vdpp::free_ion_memory(struct vdpp_ion *buf_ion_info) {
   6624 
   6625      if(!buf_ion_info) {
   6626        DEBUG_PRINT_ERROR(" ION: free called with invalid fd/allocdata");
   6627        return;
   6628      }
   6629      if(ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   6630              &buf_ion_info->ion_alloc_data.handle)) {
   6631        DEBUG_PRINT_ERROR(" ION: free failed" );
   6632      }
   6633      close(buf_ion_info->ion_device_fd);
   6634      buf_ion_info->ion_device_fd = -1;
   6635      buf_ion_info->ion_alloc_data.handle = NULL;
   6636      buf_ion_info->fd_ion_data.fd = -1;
   6637 }
   6638 #endif
   6639 void omx_vdpp::free_output_buffer_header()
   6640 {
   6641   DEBUG_PRINT_HIGH(" ALL output buffers are freed/released");
   6642   output_use_buffer = false;
   6643   ouput_egl_buffers = false;
   6644 
   6645   if (m_out_mem_ptr)
   6646   {
   6647     free (m_out_mem_ptr);
   6648     m_out_mem_ptr = NULL;
   6649   }
   6650 
   6651   if(m_platform_list)
   6652   {
   6653     free(m_platform_list);
   6654     m_platform_list = NULL;
   6655   }
   6656 
   6657   if (drv_ctx.ptr_respbuffer)
   6658   {
   6659     free (drv_ctx.ptr_respbuffer);
   6660     drv_ctx.ptr_respbuffer = NULL;
   6661   }
   6662   if (drv_ctx.ptr_outputbuffer)
   6663   {
   6664     free (drv_ctx.ptr_outputbuffer);
   6665     drv_ctx.ptr_outputbuffer = NULL;
   6666   }
   6667 #ifdef USE_ION
   6668     if (drv_ctx.op_buf_ion_info) {
   6669         DEBUG_PRINT_LOW(" Free o/p ion context");
   6670 	free(drv_ctx.op_buf_ion_info);
   6671         drv_ctx.op_buf_ion_info = NULL;
   6672     }
   6673 #endif
   6674 }
   6675 
   6676 void omx_vdpp::free_input_buffer_header()
   6677 {
   6678     input_use_buffer = false;
   6679 
   6680     if (m_inp_heap_ptr)
   6681     {
   6682       DEBUG_PRINT_LOW(" Free input Heap Pointer");
   6683       free (m_inp_heap_ptr);
   6684       m_inp_heap_ptr = NULL;
   6685     }
   6686 
   6687     if (m_phdr_pmem_ptr)
   6688     {
   6689       DEBUG_PRINT_LOW(" Free input pmem header Pointer");
   6690       free (m_phdr_pmem_ptr);
   6691       m_phdr_pmem_ptr = NULL;
   6692     }
   6693 
   6694     if (m_inp_mem_ptr)
   6695     {
   6696       DEBUG_PRINT_LOW(" Free input pmem Pointer area");
   6697       free (m_inp_mem_ptr);
   6698       m_inp_mem_ptr = NULL;
   6699     }
   6700 
   6701     if (drv_ctx.ptr_inputbuffer)
   6702     {
   6703       DEBUG_PRINT_LOW(" Free Driver Context pointer");
   6704       free (drv_ctx.ptr_inputbuffer);
   6705       drv_ctx.ptr_inputbuffer = NULL;
   6706     }
   6707 #ifdef USE_ION
   6708     if (drv_ctx.ip_buf_ion_info) {
   6709         DEBUG_PRINT_LOW(" Free ion context");
   6710 	free(drv_ctx.ip_buf_ion_info);
   6711         drv_ctx.ip_buf_ion_info = NULL;
   6712     }
   6713 #endif
   6714 }
   6715 
   6716 int omx_vdpp::stream_off(OMX_U32 port)
   6717 {
   6718 	enum v4l2_buf_type btype;
   6719 	int rc = 0;
   6720 	enum v4l2_ports v4l2_port = OUTPUT_PORT;
   6721 
   6722 	if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6723 		btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6724 		v4l2_port = OUTPUT_PORT;
   6725 	} else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6726 		btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6727 		v4l2_port = CAPTURE_PORT;
   6728 	} else if (port == OMX_ALL) {
   6729 		int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   6730 		int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   6731 
   6732 		if (!rc_input)
   6733 			return rc_input;
   6734 		else
   6735 			return rc_output;
   6736 	}
   6737 
   6738 	if (!streaming[v4l2_port]) {
   6739 		// already streamed off, warn and move on
   6740 		DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   6741 				" which is already streamed off", v4l2_port);
   6742 		return 0;
   6743 	}
   6744 
   6745 	DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   6746 #ifndef STUB_VPU
   6747 	rc = ioctl(drv_ctx.video_vpu_fd, VIDIOC_STREAMOFF, &btype);
   6748 	if (rc) {
   6749 		     DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
   6750 	} else {
   6751 		streaming[v4l2_port] = false;
   6752 	}
   6753 #endif
   6754 
   6755 	return rc;
   6756 }
   6757 
   6758 // return buffer_prop->actualcount and buffer_prop->buffer_size
   6759 // based on ip/op format
   6760 #ifdef STUB_VPU
   6761 OMX_ERRORTYPE omx_vdpp::get_buffer_req(vdpp_allocatorproperty *buffer_prop)
   6762 {
   6763     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6764     struct v4l2_requestbuffers bufreq;
   6765     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
   6766     struct v4l2_format fmt;
   6767 
   6768     int ret = 0;
   6769 
   6770     DEBUG_PRINT_HIGH("omx_vdpp::get_buffer_req GetBufReq IN: ActCnt(%d) Size(%d)",
   6771     buffer_prop->actualcount, buffer_prop->buffer_size);
   6772 
   6773     if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT){
   6774 
   6775     bufreq.count = VP_INPUT_BUFFER_COUNT_INTERLACE;
   6776     }else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT){
   6777 
   6778     bufreq.count = VP_OUTPUT_BUFFER_COUNT;
   6779     }else
   6780     {
   6781        DEBUG_PRINT_HIGH("omx_vdpp:: wrong buffer type");
   6782     }
   6783 
   6784     {
   6785         buffer_prop->actualcount = bufreq.count;
   6786         buffer_prop->mincount = bufreq.count;
   6787         DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
   6788     }
   6789 
   6790     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
   6791     buffer_prop->actualcount, buffer_prop->buffer_size);
   6792     {
   6793         buffer_prop->buffer_size = drv_ctx.video_resolution_input.frame_height *
   6794                                    paddedFrameWidth128(drv_ctx.video_resolution_input.frame_width) *
   6795                                    3 / 2; // hardcoded size for stub NV12
   6796     }
   6797     buf_size = buffer_prop->buffer_size;
   6798 
   6799     buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   6800     DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
   6801         buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
   6802     if (in_reconfig) // BufReq will be set to driver when port is disabled
   6803       buffer_prop->buffer_size = buf_size;
   6804     else if (buf_size != buffer_prop->buffer_size)
   6805     {
   6806       buffer_prop->buffer_size = buf_size;
   6807       eRet = set_buffer_req(buffer_prop);
   6808     }
   6809   //}
   6810   DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
   6811     buffer_prop->actualcount, buffer_prop->buffer_size);
   6812   return eRet;
   6813 }
   6814 
   6815 // set buffer_prop->actualcount through VIDIOC_REQBUFS
   6816 OMX_ERRORTYPE omx_vdpp::set_buffer_req(vdpp_allocatorproperty *buffer_prop)
   6817 {
   6818   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6819   unsigned buf_size = 0;
   6820   struct v4l2_format fmt;
   6821   struct v4l2_requestbuffers bufreq;
   6822   int ret;
   6823   DEBUG_PRINT_HIGH("omx_vdpp::set_buffer_req SetBufReq IN: ActCnt(%d) Size(%d)",
   6824     buffer_prop->actualcount, buffer_prop->buffer_size);
   6825   buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   6826   if (buf_size != buffer_prop->buffer_size)
   6827   {
   6828     DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
   6829       buffer_prop->buffer_size, buf_size);
   6830     eRet = OMX_ErrorBadParameter;
   6831   }
   6832 
   6833   return eRet;
   6834 }
   6835 #else
   6836 // call VIDIOC_REQBUFS to set the initial number of buffers that app wants to
   6837 // use in streaming
   6838 // return buffer_prop->buffer_size and ip/op resolution based on ip/op format
   6839 OMX_ERRORTYPE omx_vdpp::get_buffer_req(vdpp_allocatorproperty *buffer_prop)
   6840 {
   6841   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6842   struct v4l2_requestbuffers bufreq;
   6843   unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
   6844   struct v4l2_format fmt;
   6845   int ret = 0;
   6846 
   6847     memset((void *)&fmt, 0, sizeof(v4l2_format));
   6848     memset((void *)&bufreq, 0, sizeof(v4l2_requestbuffers));
   6849     DEBUG_PRINT_HIGH("GetBufReq IN: ActCnt(%d) Size(%d) buffer_prop->buffer_type (%d), streaming[OUTPUT_PORT] (%d), streaming[CAPTURE_PORT] (%d)",
   6850     buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type, streaming[OUTPUT_PORT], streaming[CAPTURE_PORT]);
   6851 	bufreq.memory = V4L2_MEMORY_USERPTR;
   6852    if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT){
   6853     bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6854 	fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6855     fmt.fmt.pix_mp.pixelformat = output_capability;
   6856     bufreq.count = VP_INPUT_BUFFER_COUNT_INTERLACE;
   6857   }else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT){
   6858     bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6859 	fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6860     fmt.fmt.pix_mp.pixelformat = capture_capability;
   6861     bufreq.count = VP_OUTPUT_BUFFER_COUNT;
   6862   }else {eRet = OMX_ErrorBadParameter;}
   6863   if(eRet==OMX_ErrorNone){
   6864   ret = ioctl(drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
   6865   }
   6866   if(ret)
   6867   {
   6868     DEBUG_PRINT_ERROR("GetBufReq Requesting buffer requirements failed 1");
   6869     eRet = OMX_ErrorInsufficientResources;
   6870     return eRet;
   6871   }
   6872   else
   6873   {
   6874     buffer_prop->actualcount = bufreq.count;
   6875     buffer_prop->mincount = bufreq.count;
   6876     DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
   6877   }
   6878   DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d), buffer_prop->buffer_type(%d) fmt.fmt.pix_mp.pixelformat (0x%08x)",
   6879     buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type, fmt.fmt.pix_mp.pixelformat);
   6880 
   6881   if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
   6882   {
   6883       fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
   6884       fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
   6885       if (V4L2_FIELD_NONE == drv_ctx.interlace)
   6886       {
   6887         fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   6888       }
   6889       else
   6890       {
   6891         fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
   6892       }
   6893 
   6894   }
   6895   else
   6896   {
   6897       fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
   6898       fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
   6899       fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   6900   }
   6901 
   6902   //ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_G_FMT, &fmt);
   6903   // S_FMT is always called before get_buffer_req
   6904   // we should be able to use G_FMT to get fmt info.
   6905   ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_TRY_FMT, &fmt);
   6906   //ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_G_FMT, &fmt);
   6907 
   6908   if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
   6909   {
   6910     drv_ctx.input_num_planes = fmt.fmt.pix_mp.num_planes;
   6911     drv_ctx.video_resolution_input.frame_height = fmt.fmt.pix_mp.height;
   6912     drv_ctx.video_resolution_input.frame_width = fmt.fmt.pix_mp.width;
   6913     DEBUG_PRINT_HIGH("GetBufReq drv_ctx.video_resolution_input.frame_height = %d, drv_ctx.video_resolution_input.frame_width = %d ",
   6914         drv_ctx.video_resolution_input.frame_height,  drv_ctx.video_resolution_input.frame_width);
   6915   }
   6916   else
   6917   {
   6918     drv_ctx.output_num_planes = fmt.fmt.pix_mp.num_planes;
   6919     drv_ctx.video_resolution_output.frame_height = fmt.fmt.pix_mp.height;
   6920     drv_ctx.video_resolution_output.frame_width = fmt.fmt.pix_mp.width;
   6921     DEBUG_PRINT_HIGH("GetBufReq drv_ctx.video_resolution_output.frame_height = %d, drv_ctx.video_resolution_output.frame_width = %d ",
   6922         drv_ctx.video_resolution_output.frame_height,  drv_ctx.video_resolution_output.frame_width);
   6923   }
   6924 
   6925   buffer_prop->frame_size = paddedFrameWidth32(fmt.fmt.pix_mp.height) *
   6926                                    paddedFrameWidth128(fmt.fmt.pix_mp.width) *
   6927                                    3 / 2;
   6928   DEBUG_PRINT_HIGH("GetBufReq fmt.fmt.pix_mp.num_planes = %d, fmt.fmt.pix_mp.height = %d, fmt.fmt.pix_mp.width = %d, buffer_prop->frame_size = %d \n",
   6929       fmt.fmt.pix_mp.num_planes, fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width, buffer_prop->frame_size);
   6930 
   6931 
   6932   if(ret)
   6933   {
   6934     DEBUG_PRINT_ERROR("GetBufReq Requesting buffer requirements failed 2");
   6935     eRet = OMX_ErrorInsufficientResources;
   6936   }
   6937   else
   6938   {
   6939     int extra_idx = 0;
   6940     buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   6941     buf_size = buffer_prop->buffer_size;
   6942     if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT)
   6943     {
   6944         extra_idx = EXTRADATA_IDX(drv_ctx.input_num_planes);
   6945     }
   6946     else
   6947     {
   6948         extra_idx = EXTRADATA_IDX(drv_ctx.output_num_planes);
   6949     }
   6950 
   6951     if ((extra_idx > 0) && (extra_idx < VIDEO_MAX_PLANES)) {
   6952       extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   6953       DEBUG_PRINT_HIGH("omx_vdpp::get_buffer_req extra_data_size: %d\n", extra_data_size);
   6954     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   6955       DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
   6956       return OMX_ErrorBadParameter;
   6957     }
   6958     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   6959     {
   6960       DEBUG_PRINT_HIGH("Frame info extra data enabled!");
   6961       client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
   6962     }
   6963     if (client_extradata & OMX_INTERLACE_EXTRADATA)
   6964     {
   6965       DEBUG_PRINT_HIGH("Interlace extra data enabled!");
   6966       client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
   6967     }
   6968     if (client_extradata & OMX_PORTDEF_EXTRADATA)
   6969     {
   6970       client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
   6971       DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
   6972          client_extra_data_size);
   6973     }
   6974     if (client_extra_data_size)
   6975     {
   6976       client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
   6977       buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
   6978     }
   6979     // update buffer_prop->buffer_size to include plane 1 buffer size
   6980     // so only 1 ION buffer will be allocated for each input/output buffer
   6981     if (extra_data_size > 0)
   6982     {
   6983         buf_size += extra_data_size;
   6984     }
   6985 
   6986     drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
   6987     drv_ctx.extradata_info.count = buffer_prop->actualcount;
   6988     drv_ctx.extradata_info.buffer_size = extra_data_size;
   6989     buf_size += client_extra_data_size; // client_extra_data_size defaults to 0
   6990     buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   6991     DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
   6992         buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
   6993     if (in_reconfig) // BufReq will be set to driver when port is disabled
   6994       buffer_prop->buffer_size = buf_size;
   6995     else if (buf_size != buffer_prop->buffer_size)
   6996     {
   6997       buffer_prop->buffer_size = buf_size;
   6998       eRet = set_buffer_req(buffer_prop);
   6999     }
   7000   }
   7001   DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d) buffer_prop->buffer_type(%d)",
   7002     buffer_prop->actualcount, buffer_prop->buffer_size, buffer_prop->buffer_type);
   7003   return eRet;
   7004 }
   7005 
   7006 // set buffer_prop->actualcount through VIDIOC_REQBUFS
   7007 OMX_ERRORTYPE omx_vdpp::set_buffer_req(vdpp_allocatorproperty *buffer_prop)
   7008 {
   7009   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7010   unsigned buf_size = 0;
   7011   unsigned i = 0;
   7012   struct v4l2_format fmt;
   7013   struct v4l2_requestbuffers bufreq;
   7014   int ret;
   7015   DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
   7016     buffer_prop->actualcount, buffer_prop->buffer_size);
   7017   memset((void *)&fmt, 0, sizeof(v4l2_format));
   7018   memset((void *)&bufreq, 0, sizeof(v4l2_requestbuffers));
   7019   buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   7020   if (buf_size != buffer_prop->buffer_size)
   7021   {
   7022     DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
   7023       buffer_prop->buffer_size, buf_size);
   7024     eRet = OMX_ErrorBadParameter;
   7025   }
   7026   else
   7027   {
   7028 
   7029 	if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT){
   7030 		fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7031 		fmt.fmt.pix_mp.pixelformat = output_capability;
   7032 
   7033         if (V4L2_FIELD_NONE == drv_ctx.interlace)
   7034         {
   7035           fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   7036         }
   7037         else
   7038         {
   7039           fmt.fmt.pix_mp.field = V4L2_FIELD_INTERLACED;
   7040         }
   7041         fmt.fmt.pix_mp.height = drv_ctx.video_resolution_input.frame_height;
   7042 	    fmt.fmt.pix_mp.width = drv_ctx.video_resolution_input.frame_width;
   7043 
   7044         setFormatParams(output_capability, drv_ctx.input_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   7045         for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   7046         {
   7047             fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
   7048                                                                      drv_ctx.input_bytesperpixel[i] *
   7049                                                                      fmt.fmt.pix_mp.height);
   7050             fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.input_bytesperpixel[0]); // both plane have the same plane stride
   7051         }
   7052 	} else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT) {
   7053 		fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7054 		fmt.fmt.pix_mp.pixelformat = capture_capability;
   7055         fmt.fmt.pix_mp.field = V4L2_FIELD_NONE;
   7056         fmt.fmt.pix_mp.height = drv_ctx.video_resolution_output.frame_height;
   7057 	    fmt.fmt.pix_mp.width = drv_ctx.video_resolution_output.frame_width;
   7058 
   7059         setFormatParams(capture_capability, drv_ctx.output_bytesperpixel, &(fmt.fmt.pix_mp.num_planes));
   7060         for( i=0; i<fmt.fmt.pix_mp.num_planes; i++ )
   7061         {
   7062             fmt.fmt.pix_mp.plane_fmt[i].sizeimage = paddedFrameWidth128(fmt.fmt.pix_mp.width *
   7063                                                                      drv_ctx.output_bytesperpixel[i] *
   7064                                                                      fmt.fmt.pix_mp.height);
   7065             fmt.fmt.pix_mp.plane_fmt[i].bytesperline = paddedFrameWidth128(fmt.fmt.pix_mp.width * drv_ctx.output_bytesperpixel[0]);
   7066             DEBUG_PRINT_HIGH("set_buffer_req fmt.fmt.pix_mp.plane_fmt[%d].sizeimage = %d \n ", i, fmt.fmt.pix_mp.plane_fmt[i].sizeimage);
   7067         }
   7068 	} else {eRet = OMX_ErrorBadParameter;}
   7069 
   7070 	ret = ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_FMT, &fmt);
   7071     if (ret)
   7072     {
   7073       DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   7074       eRet = OMX_ErrorInsufficientResources;
   7075     }
   7076     else
   7077     {
   7078          DEBUG_PRINT_HIGH("set_buffer_req drv_ctx.interlace = %d", drv_ctx.interlace);
   7079     }
   7080 
   7081 	bufreq.memory = V4L2_MEMORY_USERPTR;
   7082 	bufreq.count = buffer_prop->actualcount;
   7083 	if(buffer_prop->buffer_type == VDPP_BUFFER_TYPE_INPUT) {
   7084 		bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7085 	} else if (buffer_prop->buffer_type == VDPP_BUFFER_TYPE_OUTPUT) {
   7086 		bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7087 	} else {eRet = OMX_ErrorBadParameter;}
   7088 
   7089 	if (eRet==OMX_ErrorNone) {
   7090 		ret = ioctl(drv_ctx.video_vpu_fd,VIDIOC_REQBUFS, &bufreq);
   7091 	}
   7092 
   7093 	if (ret)
   7094 	{
   7095 		DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   7096 		eRet = OMX_ErrorInsufficientResources;
   7097 	} else if (bufreq.count < buffer_prop->actualcount) {
   7098 		DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   7099 						" on v4l2 port %d to %d (prefers %d)", bufreq.type,
   7100 						buffer_prop->actualcount, bufreq.count);
   7101 		eRet = OMX_ErrorInsufficientResources;
   7102 	}
   7103 
   7104   }
   7105   return eRet;
   7106 }
   7107 #endif
   7108 
   7109 OMX_ERRORTYPE omx_vdpp::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   7110 {
   7111   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7112   if (!portDefn)
   7113   {
   7114     return OMX_ErrorBadParameter;
   7115   }
   7116   DEBUG_PRINT_LOW("omx_vdpp::update_portdef\n");
   7117   portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   7118   portDefn->nSize = sizeof(portDefn);
   7119   portDefn->eDomain    = OMX_PortDomainVideo;
   7120   if (drv_ctx.frame_rate.fps_denominator > 0)
   7121     portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
   7122                                         drv_ctx.frame_rate.fps_denominator;
   7123   else {
   7124     DEBUG_PRINT_ERROR("Error: Divide by zero \n");
   7125     return OMX_ErrorBadParameter;
   7126   }
   7127   if (OMX_CORE_INPUT_PORT_INDEX == portDefn->nPortIndex)
   7128   {
   7129     portDefn->eDir =  OMX_DirInput;
   7130     portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   7131     portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   7132     portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   7133     portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;//OMX_COLOR_FormatYUV420Planar;//OMX_COLOR_FormatUnused;
   7134     portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   7135     portDefn->bEnabled   = m_inp_bEnabled;
   7136     portDefn->bPopulated = m_inp_bPopulated;
   7137     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution_input.frame_height;
   7138     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution_input.frame_width;
   7139     portDefn->format.video.nStride = drv_ctx.video_resolution_input.stride;
   7140     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution_input.scan_lines;
   7141   }
   7142   else if (OMX_CORE_OUTPUT_PORT_INDEX == portDefn->nPortIndex)
   7143   {
   7144     portDefn->eDir =  OMX_DirOutput;
   7145 	portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   7146 	portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   7147     portDefn->nBufferSize = drv_ctx.op_buf.buffer_size;
   7148     portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   7149     portDefn->bEnabled   = m_out_bEnabled;
   7150     portDefn->bPopulated = m_out_bPopulated;
   7151     portDefn->format.video.eColorFormat = (OMX_COLOR_FORMATTYPE) QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   7152 
   7153     // video_resolution_output.frame_height is retrieved from get_bufreq
   7154     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution_output.frame_height;
   7155     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution_output.frame_width;
   7156     portDefn->format.video.nStride = drv_ctx.video_resolution_output.stride;
   7157     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution_output.scan_lines;
   7158   }
   7159   else
   7160   {
   7161       portDefn->eDir = OMX_DirMax;
   7162     DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   7163              (int)portDefn->nPortIndex);
   7164     eRet = OMX_ErrorBadPortIndex;
   7165   }
   7166 
   7167   DEBUG_PRINT_HIGH("update_portdef for %lu Width = %lu Height = %lu Stride = %ld SliceHeight = %lu portDefn->format.video.eColorFormat = %d \n", portDefn->nPortIndex,
   7168     portDefn->format.video.nFrameWidth,
   7169     portDefn->format.video.nFrameHeight,
   7170     portDefn->format.video.nStride,
   7171     portDefn->format.video.nSliceHeight,
   7172     portDefn->format.video.eColorFormat);
   7173   return eRet;
   7174 
   7175 }
   7176 
   7177 OMX_ERRORTYPE omx_vdpp::allocate_output_headers()
   7178 {
   7179   OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7180   OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   7181   unsigned i= 0;
   7182 
   7183   if(!m_out_mem_ptr) {
   7184     DEBUG_PRINT_HIGH(" Use o/p buffer case - Header List allocation");
   7185     int nBufHdrSize        = 0;
   7186     int nPlatformEntrySize = 0;
   7187     int nPlatformListSize  = 0;
   7188     int nPMEMInfoSize = 0;
   7189     OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   7190     OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   7191     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   7192 
   7193     DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
   7194       drv_ctx.op_buf.actualcount);
   7195     nBufHdrSize        = drv_ctx.op_buf.actualcount *
   7196                          sizeof(OMX_BUFFERHEADERTYPE);
   7197 
   7198     DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d \n",nBufHdrSize,
   7199                          sizeof(OMX_BUFFERHEADERTYPE));
   7200 
   7201     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   7202 
   7203     drv_ctx.ptr_outputbuffer = (struct vdpp_bufferpayload *) \
   7204       calloc (sizeof(struct vdpp_bufferpayload),
   7205       drv_ctx.op_buf.actualcount);
   7206     drv_ctx.ptr_respbuffer = (struct vdpp_output_frameinfo  *)\
   7207       calloc (sizeof (struct vdpp_output_frameinfo),
   7208       drv_ctx.op_buf.actualcount);
   7209 #ifdef USE_ION
   7210     drv_ctx.op_buf_ion_info = (struct vdpp_ion * ) \
   7211       calloc (sizeof(struct vdpp_ion),drv_ctx.op_buf.actualcount);
   7212 
   7213       if (!drv_ctx.op_buf_ion_info) {
   7214           DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   7215           return OMX_ErrorInsufficientResources;
   7216       }
   7217 #endif
   7218 
   7219     if(m_out_mem_ptr && drv_ctx.ptr_outputbuffer
   7220        && drv_ctx.ptr_respbuffer)
   7221     {
   7222       bufHdr          =  m_out_mem_ptr;
   7223       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   7224 
   7225       for(i=0; i < drv_ctx.op_buf.actualcount ; i++)
   7226       {
   7227         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   7228         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   7229         // Set the values when we determine the right HxW param
   7230         bufHdr->nAllocLen          = 0;
   7231         bufHdr->nFilledLen         = 0;
   7232         bufHdr->pAppPrivate        = NULL;
   7233         bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   7234         bufHdr->pBuffer            = NULL; // since no buffer is allocated
   7235 
   7236         drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   7237 #ifdef USE_ION
   7238         drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   7239 #endif
   7240         /*Create a mapping between buffers*/
   7241         bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   7242         drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   7243                                             &drv_ctx.ptr_outputbuffer[i];
   7244         // Move the buffer and buffer header pointers
   7245         bufHdr++;
   7246       }
   7247     }
   7248     else
   7249     {
   7250       DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p]\n",\
   7251                                         m_out_mem_ptr);
   7252       if(m_out_mem_ptr)
   7253       {
   7254         free(m_out_mem_ptr);
   7255         m_out_mem_ptr = NULL;
   7256       }
   7257 
   7258       if(drv_ctx.ptr_outputbuffer)
   7259       {
   7260         free(drv_ctx.ptr_outputbuffer);
   7261         drv_ctx.ptr_outputbuffer = NULL;
   7262       }
   7263       if(drv_ctx.ptr_respbuffer)
   7264       {
   7265         free(drv_ctx.ptr_respbuffer);
   7266         drv_ctx.ptr_respbuffer = NULL;
   7267       }
   7268 #ifdef USE_ION
   7269     if (drv_ctx.op_buf_ion_info) {
   7270         DEBUG_PRINT_LOW(" Free o/p ion context");
   7271 	free(drv_ctx.op_buf_ion_info);
   7272         drv_ctx.op_buf_ion_info = NULL;
   7273     }
   7274 #endif
   7275       eRet =  OMX_ErrorInsufficientResources;
   7276     }
   7277   } else {
   7278     eRet =  OMX_ErrorInsufficientResources;
   7279   }
   7280   return eRet;
   7281 }
   7282 
   7283 void omx_vdpp::complete_pending_buffer_done_cbs()
   7284 {
   7285   unsigned p1;
   7286   unsigned p2;
   7287   unsigned ident;
   7288   omx_cmd_queue tmp_q, pending_bd_q;
   7289   pthread_mutex_lock(&m_lock);
   7290   // pop all pending GENERATE FDB from ftb queue
   7291   while (m_ftb_q.m_size)
   7292   {
   7293     m_ftb_q.pop_entry(&p1,&p2,&ident);
   7294     if(ident == OMX_COMPONENT_GENERATE_FBD)
   7295     {
   7296       pending_bd_q.insert_entry(p1,p2,ident);
   7297     }
   7298     else
   7299     {
   7300       tmp_q.insert_entry(p1,p2,ident);
   7301     }
   7302   }
   7303   //return all non GENERATE FDB to ftb queue
   7304   while(tmp_q.m_size)
   7305   {
   7306     tmp_q.pop_entry(&p1,&p2,&ident);
   7307     m_ftb_q.insert_entry(p1,p2,ident);
   7308   }
   7309   // pop all pending GENERATE EDB from etb queue
   7310   while (m_etb_q.m_size)
   7311   {
   7312     m_etb_q.pop_entry(&p1,&p2,&ident);
   7313     if(ident == OMX_COMPONENT_GENERATE_EBD)
   7314     {
   7315       pending_bd_q.insert_entry(p1,p2,ident);
   7316     }
   7317     else
   7318     {
   7319       tmp_q.insert_entry(p1,p2,ident);
   7320     }
   7321   }
   7322   //return all non GENERATE FDB to etb queue
   7323   while(tmp_q.m_size)
   7324   {
   7325     tmp_q.pop_entry(&p1,&p2,&ident);
   7326     m_etb_q.insert_entry(p1,p2,ident);
   7327   }
   7328   pthread_mutex_unlock(&m_lock);
   7329   // process all pending buffer dones
   7330   while(pending_bd_q.m_size)
   7331   {
   7332     pending_bd_q.pop_entry(&p1,&p2,&ident);
   7333     switch(ident)
   7334     {
   7335       case OMX_COMPONENT_GENERATE_EBD:
   7336         if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
   7337         {
   7338           DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!\n");
   7339           omx_report_error ();
   7340         }
   7341         break;
   7342 
   7343       case OMX_COMPONENT_GENERATE_FBD:
   7344         if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
   7345         {
   7346           DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!\n");
   7347           omx_report_error ();
   7348         }
   7349         break;
   7350     }
   7351   }
   7352 }
   7353 
   7354 void omx_vdpp::set_frame_rate(OMX_S64 act_timestamp)
   7355 {
   7356 // No framerate control on 8084 VPU. This API is for 8092.
   7357 #ifdef FRC_ENABLE
   7358   OMX_U32 new_frame_interval = 0;
   7359   if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   7360      && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000))
   7361   {
   7362     new_frame_interval = (act_timestamp > prev_ts)?
   7363                           act_timestamp - prev_ts :
   7364                           prev_ts - act_timestamp;
   7365     if (new_frame_interval < frm_int || frm_int == 0)
   7366     {
   7367       frm_int = new_frame_interval;
   7368       if(frm_int)
   7369       {
   7370         drv_ctx.frame_rate.fps_numerator = 1e6;
   7371         drv_ctx.frame_rate.fps_denominator = frm_int;
   7372         DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
   7373                          frm_int, drv_ctx.frame_rate.fps_numerator /
   7374                          (float)drv_ctx.frame_rate.fps_denominator);
   7375 
   7376         /* We need to report the difference between this FBD and the previous FBD
   7377          * back to the driver for clock scaling purposes. */
   7378         struct v4l2_outputparm oparm;
   7379         /*XXX: we're providing timing info as seconds per frame rather than frames
   7380          * per second.*/
   7381         oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   7382         oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   7383 
   7384         struct v4l2_streamparm sparm;
   7385         sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7386         sparm.parm.output = oparm;
   7387         if (ioctl(drv_ctx.video_vpu_fd, VIDIOC_S_PARM, &sparm))
   7388         {
   7389             DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   7390                     performance might be affected");
   7391         }
   7392 
   7393       }
   7394     }
   7395   }
   7396   prev_ts = act_timestamp;
   7397 #endif
   7398 }
   7399 
   7400 void omx_vdpp::adjust_timestamp(OMX_S64 &act_timestamp)
   7401 {
   7402   if (rst_prev_ts && VALID_TS(act_timestamp))
   7403   {
   7404     prev_ts = act_timestamp;
   7405     rst_prev_ts = false;
   7406   }
   7407   else if (VALID_TS(prev_ts))
   7408   {
   7409     bool codec_cond = (drv_ctx.timestamp_adjust)?
   7410                       (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
   7411                       (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
   7412                       (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
   7413     if(frm_int > 0 && codec_cond)
   7414     {
   7415       DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   7416       act_timestamp = prev_ts + frm_int;
   7417       DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   7418       prev_ts = act_timestamp;
   7419     }
   7420     else
   7421       set_frame_rate(act_timestamp);
   7422   }
   7423   else if (frm_int > 0)           // In this case the frame rate was set along
   7424   {                               // with the port definition, start ts with 0
   7425     act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   7426     rst_prev_ts = true;
   7427   }
   7428 }
   7429 
   7430 OMX_ERRORTYPE omx_vdpp::enable_extradata(OMX_U32 requested_extradata, bool enable)
   7431 {
   7432   OMX_ERRORTYPE ret = OMX_ErrorNone;
   7433   if(m_state != OMX_StateLoaded)
   7434   {
   7435      DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   7436      return OMX_ErrorIncorrectStateOperation;
   7437   }
   7438   DEBUG_PRINT_ERROR("enable_extradata: actual[%lx] requested[%lx] enable[%d]",
   7439     client_extradata, requested_extradata, enable);
   7440 
   7441   if (enable)
   7442     client_extradata |= requested_extradata;
   7443   else
   7444     client_extradata = client_extradata & ~requested_extradata;
   7445 
   7446   return ret;
   7447 }
   7448 
   7449 void omx_vdpp::setFormatParams(int pixelFormat, double bytesperpixel[], unsigned char *planesCount)
   7450 {
   7451 	/*24 RGB-8-8-8 */
   7452     switch (pixelFormat)
   7453     {
   7454         case V4L2_PIX_FMT_RGB24:
   7455             *planesCount = 0;
   7456 		    bytesperpixel[0] = 3;
   7457             break;
   7458 
   7459             /*32 ARGB-8-8-8-8 */
   7460         case V4L2_PIX_FMT_RGB32:
   7461             *planesCount = 0;
   7462 		    bytesperpixel[0] = 4;
   7463             break;
   7464 
   7465 	        /*32 ARGB-2-10-10-10*/
   7466         case V4L2_PIX_FMT_XRGB2:
   7467             *planesCount = 0;
   7468 		    bytesperpixel[0] = 4;
   7469             break;
   7470 
   7471 	        /*24  BGR-8-8-8 */
   7472         case V4L2_PIX_FMT_BGR24:
   7473             *planesCount = 0;
   7474 		    bytesperpixel[0] = 3;
   7475             break;
   7476 
   7477 	        /*32  BGRX-8-8-8-8 */
   7478         case V4L2_PIX_FMT_BGR32:
   7479             *planesCount = 0;
   7480 		    bytesperpixel[0] = 4;
   7481             break;
   7482 
   7483 	    /*32  XBGR-2-10-10-10*/
   7484         case V4L2_PIX_FMT_XBGR2:
   7485             *planesCount = 0;
   7486 		    bytesperpixel[0] = 4;
   7487             break;
   7488 
   7489 	    /*12  YUV 4:2:0  semi-planar*/
   7490         case V4L2_PIX_FMT_NV12:
   7491             *planesCount = 2;
   7492 		    bytesperpixel[0] = 1;
   7493 		    bytesperpixel[1] = 0.5;
   7494             break;
   7495 
   7496 	    /*12  YVU 4:2:0  semi-planar*/
   7497         case V4L2_PIX_FMT_NV21:
   7498             *planesCount = 2;
   7499 		    bytesperpixel[0] = 1;
   7500 		    bytesperpixel[1] = 0.5;
   7501             break;
   7502 
   7503 	    /* 16 YUYV 4:2:2 interleaved*/
   7504         case V4L2_PIX_FMT_YUYV:
   7505             *planesCount = 2;
   7506 		    bytesperpixel[0] = 2;
   7507 		    bytesperpixel[1] = 0.5;
   7508             break;
   7509 
   7510 	    /* 16 YVYU 4:2:2 interleaved*/
   7511         case V4L2_PIX_FMT_YVYU:
   7512             *planesCount = 1;
   7513 		    bytesperpixel[0] = 2;
   7514             break;
   7515 
   7516 	    /* 16 VYUY 4:2:2 interleaved*/
   7517         case V4L2_PIX_FMT_VYUY:
   7518             *planesCount = 1;
   7519 		    bytesperpixel[0] = 2;
   7520             break;
   7521 
   7522 	    /* 16 UYVY 4:2:2 interleaved*/
   7523         case V4L2_PIX_FMT_UYVY:
   7524             *planesCount = 1;
   7525 		    bytesperpixel[0] = 2;
   7526             break;
   7527 
   7528         default:
   7529 		    DEBUG_PRINT_ERROR("%s: ERROR: pixel format %d is not supported!\n",
   7530 				__func__, pixelFormat);
   7531     }
   7532 
   7533 }
   7534 
   7535 int omx_vdpp::openInput(const char* inputName)
   7536 {
   7537     int fd = -1;
   7538     const char *dirname = "/sys/class/video4linux";
   7539     char devname[PATH_MAX];
   7540     char dev[PATH_MAX];
   7541     char *filename;
   7542     DIR *dir;
   7543     struct dirent *de;
   7544     dir = opendir(dirname);
   7545     if(dir == NULL)
   7546         return -1;
   7547     strlcpy(dev, dirname, sizeof(dev));
   7548     filename = dev + strlen(dev);
   7549     *filename++ = '/';
   7550     while((de = readdir(dir)))
   7551     {
   7552         if(de->d_name[0] == '.' &&
   7553                 (de->d_name[1] == '\0' ||
   7554                  (de->d_name[1] == '.' && de->d_name[2] == '\0')))
   7555             continue;
   7556         strlcpy(filename, de->d_name, PATH_MAX - sizeof(dev) - 1);
   7557         /*DEBUG_PRINT_LOW("Filename found: %s\n", filename);*/
   7558         char name[80];
   7559         int fd_devname;
   7560         int result;
   7561         strlcpy(devname, dev, sizeof(devname));
   7562         strlcat(devname, "/name", sizeof(devname));
   7563         /*DEBUG_PRINT_LOW("opening name file: %s\n", devname);*/
   7564         /* find and read device node names from sys/conf/video4linux dir*/
   7565         fd_devname = open(devname,O_RDONLY);
   7566         if(fd_devname < 0)
   7567             DEBUG_PRINT_ERROR("openInput: could not find device name.\n");
   7568         result = read(fd_devname, name, strlen(inputName));
   7569         if(result < 0)
   7570         {
   7571             DEBUG_PRINT_ERROR("openInput: could not read device name.\n");
   7572         }
   7573         else
   7574         {
   7575             if(!strcmp(name, inputName))
   7576             {
   7577                 close(fd_devname);
   7578                 /* open the vpu driver node found from /dev dir */
   7579                 char temp[80];
   7580                 strlcpy(temp, "/dev/", sizeof(temp));
   7581                 strlcat(temp, filename, sizeof(temp));
   7582                 DEBUG_PRINT_LOW("openInput: opening device: %s\n", temp);
   7583                 fd = open(temp, O_RDWR | O_NONBLOCK);
   7584                 if(fd < 0)
   7585                     DEBUG_PRINT_ERROR("openInput: Error opening device %s\n", temp);
   7586                 else
   7587                     break;
   7588             }
   7589         }
   7590         close(fd_devname);
   7591     }
   7592     closedir(dir);
   7593     ALOGE_IF(fd<0, "couldn't find '%s' input device", inputName);
   7594     return fd;
   7595 }
   7596