Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2013, 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_vdec.cpp
     34   This module contains the implementation of the OpenMAX core & component.
     35 
     36 *//*========================================================================*/
     37 
     38 //////////////////////////////////////////////////////////////////////////////
     39 //                             Include Files
     40 //////////////////////////////////////////////////////////////////////////////
     41 
     42 #include <string.h>
     43 #include <pthread.h>
     44 #include <sys/prctl.h>
     45 #include <unistd.h>
     46 #include <errno.h>
     47 #include "omx_vdec.h"
     48 #include <fcntl.h>
     49 #include <limits.h>
     50 #include <stdlib.h>
     51 #include <media/hardware/HardwareAPI.h>
     52 #include <media/msm_media_info.h>
     53 
     54 #ifndef _ANDROID_
     55 #include <sys/ioctl.h>
     56 #include <sys/mman.h>
     57 #endif //_ANDROID_
     58 
     59 #ifdef _ANDROID_
     60 #include <cutils/properties.h>
     61 #include <gralloc_priv.h>
     62 #undef USE_EGL_IMAGE_GPU
     63 #endif
     64 
     65 #include <qdMetaData.h>
     66 
     67 #ifdef _ANDROID_
     68 #include "DivXDrmDecrypt.h"
     69 #endif //_ANDROID_
     70 
     71 #ifdef USE_EGL_IMAGE_GPU
     72 #include <EGL/egl.h>
     73 #include <EGL/eglQCOM.h>
     74 #define EGL_BUFFER_HANDLE_QCOM 0x4F00
     75 #define EGL_BUFFER_OFFSET_QCOM 0x4F01
     76 #endif
     77 #ifdef INPUT_BUFFER_LOG
     78 #define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
     79 #define INPUT_BUFFER_FILE_NAME_LEN 30
     80 FILE *inputBufferFile1;
     81 char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
     82 #endif
     83 #ifdef OUTPUT_BUFFER_LOG
     84 FILE *outputBufferFile1;
     85 char outputfilename [] = "/data/output.yuv";
     86 
     87 #endif
     88 #ifdef OUTPUT_EXTRADATA_LOG
     89 FILE *outputExtradataFile;
     90 char ouputextradatafilename [] = "/data/extradata";
     91 #endif
     92 
     93 #define DEFAULT_FPS 30
     94 #define MAX_INPUT_ERROR DEFAULT_FPS
     95 #define MAX_SUPPORTED_FPS 120
     96 
     97 #define VC1_SP_MP_START_CODE        0xC5000000
     98 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     99 #define VC1_AP_SEQ_START_CODE       0x0F010000
    100 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
    101 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
    102 #define VC1_SIMPLE_PROFILE          0
    103 #define VC1_MAIN_PROFILE            1
    104 #define VC1_ADVANCE_PROFILE         3
    105 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
    106 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
    107 #define VC1_STRUCT_C_LEN            4
    108 #define VC1_STRUCT_C_POS            8
    109 #define VC1_STRUCT_A_POS            12
    110 #define VC1_STRUCT_B_POS            24
    111 #define VC1_SEQ_LAYER_SIZE          36
    112 #define POLL_TIMEOUT 0x7fffffff
    113 
    114 #define MEM_DEVICE "/dev/ion"
    115 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    116 
    117 #ifdef _ANDROID_
    118 extern "C" {
    119 #include<utils/Log.h>
    120 }
    121 #endif//_ANDROID_
    122 
    123 #define SZ_4K 0x1000
    124 #define SZ_1M 0x100000
    125 
    126 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    127 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    128 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
    129 
    130 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
    131 void* async_message_thread (void *input)
    132 {
    133     OMX_BUFFERHEADERTYPE *buffer;
    134     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    135     struct pollfd pfd;
    136     struct v4l2_buffer v4l2_buf;
    137     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    138     struct v4l2_event dqevent;
    139     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
    140     pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    141     pfd.fd = omx->drv_ctx.video_driver_fd;
    142     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    143     DEBUG_PRINT_HIGH("omx_vdec: Async thread start\n");
    144     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
    145     while (1) {
    146         rc = poll(&pfd, 1, POLL_TIMEOUT);
    147         if (!rc) {
    148             DEBUG_PRINT_ERROR("Poll timedout\n");
    149             break;
    150         } else if (rc < 0) {
    151             DEBUG_PRINT_ERROR("Error while polling: %d\n", rc);
    152             break;
    153         }
    154         if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
    155             struct vdec_msginfo vdec_msg;
    156             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    157             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    158             v4l2_buf.length = omx->drv_ctx.num_planes;
    159             v4l2_buf.m.planes = plane;
    160             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    161                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    162                 vdec_msg.status_code=VDEC_S_SUCCESS;
    163                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    164                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
    165                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
    166                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    167                     (uint64_t)v4l2_buf.timestamp.tv_usec;
    168                 if (vdec_msg.msgdata.output_frame.len) {
    169                     vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
    170                     vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
    171                     vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
    172                     vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
    173                 }
    174                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    175                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    176                     break;
    177                 }
    178             }
    179         }
    180         if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
    181             struct vdec_msginfo vdec_msg;
    182             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    183             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    184             v4l2_buf.length = 1;
    185             v4l2_buf.m.planes = plane;
    186             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    187                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
    188                 vdec_msg.status_code=VDEC_S_SUCCESS;
    189                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    190                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    191                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    192                     break;
    193                 }
    194             }
    195         }
    196         if (pfd.revents & POLLPRI) {
    197             rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
    198             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
    199                 struct vdec_msginfo vdec_msg;
    200                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    201                 vdec_msg.status_code=VDEC_S_SUCCESS;
    202                 DEBUG_PRINT_HIGH("\n VIDC Port Reconfig recieved insufficient\n");
    203                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    204                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    205                     break;
    206                 }
    207             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    208                 struct vdec_msginfo vdec_msg;
    209                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
    210                 vdec_msg.status_code=VDEC_S_SUCCESS;
    211                 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved \n");
    212                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    213                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    214                     break;
    215                 }
    216                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
    217                 vdec_msg.status_code=VDEC_S_SUCCESS;
    218                 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved \n");
    219                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    220                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    221                     break;
    222                 }
    223             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
    224                 DEBUG_PRINT_HIGH("\n VIDC Close Done Recieved and async_message_thread Exited \n");
    225                 break;
    226             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    227                 struct vdec_msginfo vdec_msg;
    228                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
    229                 vdec_msg.status_code=VDEC_S_SUCCESS;
    230                 DEBUG_PRINT_HIGH("\n SYS Error Recieved \n");
    231                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    232                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    233                     break;
    234                 }
    235             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
    236                 unsigned int *ptr = (unsigned int *)dqevent.u.data;
    237                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d\n", ptr[0], ptr[1]);
    238                 omx->buf_ref_remove(ptr[0], ptr[1]);
    239             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
    240                 unsigned int *ptr = (unsigned int *)dqevent.u.data;
    241                 struct vdec_msginfo vdec_msg;
    242 
    243                 DEBUG_PRINT_HIGH("Release unqueued buffer event recvd fd = %d offset = %d\n", ptr[0], ptr[1]);
    244 
    245                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    246                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    247                 v4l2_buf.length = omx->drv_ctx.num_planes;
    248                 v4l2_buf.m.planes = plane;
    249                 v4l2_buf.index = ptr[5];
    250                 v4l2_buf.flags = 0;
    251 
    252                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    253                 vdec_msg.status_code=VDEC_S_SUCCESS;
    254                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
    255                 vdec_msg.msgdata.output_frame.len = 0;
    256                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)ptr[2];
    257                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)ptr[3] * (uint64_t)1000000) +
    258                     (uint64_t)ptr[4];
    259                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    260                     DEBUG_PRINT_HIGH("\n async_message_thread Exited  \n");
    261                     break;
    262                 }
    263             }
    264             else {
    265                 DEBUG_PRINT_HIGH("\n VIDC Some Event recieved \n");
    266                 continue;
    267             }
    268         }
    269     }
    270     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop\n");
    271     return NULL;
    272 }
    273 
    274 void* message_thread(void *input)
    275 {
    276     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    277     unsigned char id;
    278     int n;
    279 
    280     DEBUG_PRINT_HIGH("omx_vdec: message thread start\n");
    281     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
    282     while (1) {
    283 
    284         n = read(omx->m_pipe_in, &id, 1);
    285 
    286         if (0 == n) {
    287             break;
    288         }
    289 
    290         if (1 == n) {
    291             omx->process_event_cb(omx, id);
    292         }
    293         if ((n < 0) && (errno != EINTR)) {
    294             DEBUG_PRINT_LOW("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
    295             break;
    296         }
    297     }
    298     DEBUG_PRINT_HIGH("omx_vdec: message thread stop\n");
    299     return 0;
    300 }
    301 
    302 void post_message(omx_vdec *omx, unsigned char id)
    303 {
    304     int ret_value;
    305     DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d\n", id,omx->m_pipe_out);
    306     ret_value = write(omx->m_pipe_out, &id, 1);
    307     DEBUG_PRINT_LOW("post_message to pipe done %d\n",ret_value);
    308 }
    309 
    310 // omx_cmd_queue destructor
    311 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    312 {
    313     // Nothing to do
    314 }
    315 
    316 // omx cmd queue constructor
    317 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    318 {
    319     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    320 }
    321 
    322 // omx cmd queue insert
    323 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
    324 {
    325     bool ret = true;
    326     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    327         m_q[m_write].id       = id;
    328         m_q[m_write].param1   = p1;
    329         m_q[m_write].param2   = p2;
    330         m_write++;
    331         m_size ++;
    332         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    333             m_write = 0;
    334         }
    335     } else {
    336         ret = false;
    337         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full\n", __func__);
    338     }
    339     return ret;
    340 }
    341 
    342 // omx cmd queue pop
    343 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
    344 {
    345     bool ret = true;
    346     if (m_size > 0) {
    347         *id = m_q[m_read].id;
    348         *p1 = m_q[m_read].param1;
    349         *p2 = m_q[m_read].param2;
    350         // Move the read pointer ahead
    351         ++m_read;
    352         --m_size;
    353         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    354             m_read = 0;
    355         }
    356     } else {
    357         ret = false;
    358     }
    359     return ret;
    360 }
    361 
    362 // Retrieve the first mesg type in the queue
    363 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    364 {
    365     return m_q[m_read].id;
    366 }
    367 
    368 #ifdef _ANDROID_
    369 omx_vdec::ts_arr_list::ts_arr_list()
    370 {
    371     //initialize timestamps array
    372     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    373 }
    374 omx_vdec::ts_arr_list::~ts_arr_list()
    375 {
    376     //free m_ts_arr_list?
    377 }
    378 
    379 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
    380 {
    381     bool ret = true;
    382     bool duplicate_ts = false;
    383     int idx = 0;
    384 
    385     //insert at the first available empty location
    386     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    387         if (!m_ts_arr_list[idx].valid) {
    388             //found invalid or empty entry, save timestamp
    389             m_ts_arr_list[idx].valid = true;
    390             m_ts_arr_list[idx].timestamp = ts;
    391             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    392                     ts, idx);
    393             break;
    394         }
    395     }
    396 
    397     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
    398         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    399         ret = false;
    400     }
    401     return ret;
    402 }
    403 
    404 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    405 {
    406     bool ret = true;
    407     int min_idx = -1;
    408     OMX_TICKS min_ts = 0;
    409     int idx = 0;
    410 
    411     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    412 
    413         if (m_ts_arr_list[idx].valid) {
    414             //found valid entry, save index
    415             if (min_idx < 0) {
    416                 //first valid entry
    417                 min_ts = m_ts_arr_list[idx].timestamp;
    418                 min_idx = idx;
    419             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
    420                 min_ts = m_ts_arr_list[idx].timestamp;
    421                 min_idx = idx;
    422             }
    423         }
    424 
    425     }
    426 
    427     if (min_idx < 0) {
    428         //no valid entries found
    429         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    430         ts = 0;
    431         ret = false;
    432     } else {
    433         ts = m_ts_arr_list[min_idx].timestamp;
    434         m_ts_arr_list[min_idx].valid = false;
    435         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    436                 ts, min_idx);
    437     }
    438 
    439     return ret;
    440 
    441 }
    442 
    443 
    444 bool omx_vdec::ts_arr_list::reset_ts_list()
    445 {
    446     bool ret = true;
    447     int idx = 0;
    448 
    449     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    450     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    451         m_ts_arr_list[idx].valid = false;
    452     }
    453     return ret;
    454 }
    455 #endif
    456 
    457 // factory function executed by the core to create instances
    458 void *get_omx_component_factory_fn(void)
    459 {
    460     return (new omx_vdec);
    461 }
    462 
    463 #ifdef _ANDROID_
    464 #ifdef USE_ION
    465 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
    466         struct ion_handle *handle, int ionMapfd)
    467 {
    468     //    ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
    469 }
    470 #else
    471 VideoHeap::VideoHeap(int fd, size_t size, void* base)
    472 {
    473     // dup file descriptor, map once, use pmem
    474     init(dup(fd), base, size, 0 , MEM_DEVICE);
    475 }
    476 #endif
    477 #endif // _ANDROID_
    478 /* ======================================================================
    479    FUNCTION
    480    omx_vdec::omx_vdec
    481 
    482    DESCRIPTION
    483    Constructor
    484 
    485    PARAMETERS
    486    None
    487 
    488    RETURN VALUE
    489    None.
    490    ========================================================================== */
    491 omx_vdec::omx_vdec(): m_error_propogated(false),
    492     m_state(OMX_StateInvalid),
    493     m_app_data(NULL),
    494     m_inp_mem_ptr(NULL),
    495     m_out_mem_ptr(NULL),
    496     m_inp_err_count(0),
    497     input_flush_progress (false),
    498     output_flush_progress (false),
    499     input_use_buffer (false),
    500     output_use_buffer (false),
    501     ouput_egl_buffers(false),
    502     m_use_output_pmem(OMX_FALSE),
    503     m_out_mem_region_smi(OMX_FALSE),
    504     m_out_pvt_entry_pmem(OMX_FALSE),
    505     pending_input_buffers(0),
    506     pending_output_buffers(0),
    507     m_out_bm_count(0),
    508     m_inp_bm_count(0),
    509     m_inp_bPopulated(OMX_FALSE),
    510     m_out_bPopulated(OMX_FALSE),
    511     m_flags(0),
    512 #ifdef _ANDROID_
    513     m_heap_ptr(NULL),
    514 #endif
    515     m_inp_bEnabled(OMX_TRUE),
    516     m_out_bEnabled(OMX_TRUE),
    517     m_in_alloc_cnt(0),
    518     m_platform_list(NULL),
    519     m_platform_entry(NULL),
    520     m_pmem_info(NULL),
    521     arbitrary_bytes (true),
    522     psource_frame (NULL),
    523     pdest_frame (NULL),
    524     m_inp_heap_ptr (NULL),
    525     m_phdr_pmem_ptr(NULL),
    526     m_heap_inp_bm_count (0),
    527     codec_type_parse ((codec_type)0),
    528     first_frame_meta (true),
    529     frame_count (0),
    530     nal_count (0),
    531     nal_length(0),
    532     look_ahead_nal (false),
    533     first_frame(0),
    534     first_buffer(NULL),
    535     first_frame_size (0),
    536     m_device_file_ptr(NULL),
    537     m_vc1_profile((vc1_profile_type)0),
    538     m_profile(0),
    539     mInSmoothstreamingMode(false),
    540     h264_last_au_ts(LLONG_MAX),
    541     h264_last_au_flags(0),
    542     prev_ts(LLONG_MAX),
    543     rst_prev_ts(true),
    544     frm_int(0),
    545     m_disp_hor_size(0),
    546     m_disp_vert_size(0),
    547     in_reconfig(false),
    548     m_display_id(NULL),
    549     h264_parser(NULL),
    550     client_extradata(0),
    551     m_reject_avc_1080p_mp (0),
    552 #ifdef _ANDROID_
    553     m_enable_android_native_buffers(OMX_FALSE),
    554     m_use_android_native_buffers(OMX_FALSE),
    555     iDivXDrmDecrypt(NULL),
    556 #endif
    557     m_desc_buffer_ptr(NULL),
    558     secure_mode(false),
    559     client_set_fps(false),
    560     out_dynamic_list(NULL)
    561 {
    562     /* Assumption is that , to begin with , we have all the frames with decoder */
    563     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
    564 #ifdef _ANDROID_
    565     char property_value[PROPERTY_VALUE_MAX] = {0};
    566     property_get("vidc.dec.debug.perf", property_value, "0");
    567     perf_flag = atoi(property_value);
    568     if (perf_flag) {
    569         DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
    570         dec_time.start();
    571         proc_frms = latency = 0;
    572     }
    573     prev_n_filled_len = 0;
    574     property_value[0] = '\0';
    575     property_get("vidc.dec.debug.ts", property_value, "0");
    576     m_debug_timestamp = atoi(property_value);
    577     DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
    578     if (m_debug_timestamp) {
    579         time_stamp_dts.set_timestamp_reorder_mode(true);
    580         time_stamp_dts.enable_debug_print(true);
    581     }
    582 
    583     property_value[0] = '\0';
    584     property_get("vidc.dec.debug.concealedmb", property_value, "0");
    585     m_debug_concealedmb = atoi(property_value);
    586     DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
    587 
    588     property_value[0] = '\0';
    589     property_get("vidc.dec.profile.check", property_value, "0");
    590     m_reject_avc_1080p_mp = atoi(property_value);
    591     DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
    592 
    593 #endif
    594     memset(&m_cmp,0,sizeof(m_cmp));
    595     memset(&m_cb,0,sizeof(m_cb));
    596     memset (&drv_ctx,0,sizeof(drv_ctx));
    597     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    598     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    599     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
    600     m_demux_entries = 0;
    601     msg_thread_id = 0;
    602     async_thread_id = 0;
    603     msg_thread_created = false;
    604     async_thread_created = false;
    605 #ifdef _ANDROID_ICS_
    606     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    607 #endif
    608     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
    609     drv_ctx.timestamp_adjust = false;
    610     drv_ctx.video_driver_fd = -1;
    611     m_vendor_config.pData = NULL;
    612     pthread_mutex_init(&m_lock, NULL);
    613     pthread_mutex_init(&c_lock, NULL);
    614     pthread_mutex_init(&e_lock, NULL);
    615     sem_init(&m_cmd_lock,0,0);
    616     streaming[CAPTURE_PORT] =
    617         streaming[OUTPUT_PORT] = false;
    618 #ifdef _ANDROID_
    619     char extradata_value[PROPERTY_VALUE_MAX] = {0};
    620     property_get("vidc.dec.debug.extradata", extradata_value, "0");
    621     m_debug_extradata = atoi(extradata_value);
    622     DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
    623 #endif
    624     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    625     client_buffers.set_vdec_client(this);
    626     dynamic_buf_mode = false;
    627 }
    628 
    629 static const int event_type[] = {
    630     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    631     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
    632     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
    633     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
    634     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
    635     V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
    636     V4L2_EVENT_MSM_VIDC_SYS_ERROR
    637 };
    638 
    639 static OMX_ERRORTYPE subscribe_to_events(int fd)
    640 {
    641     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    642     struct v4l2_event_subscription sub;
    643     int array_sz = sizeof(event_type)/sizeof(int);
    644     int i,rc;
    645     if (fd < 0) {
    646         printf("Invalid input: %d\n", fd);
    647         return OMX_ErrorBadParameter;
    648     }
    649 
    650     for (i = 0; i < array_sz; ++i) {
    651         memset(&sub, 0, sizeof(sub));
    652         sub.type = event_type[i];
    653         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    654         if (rc) {
    655             printf("Failed to subscribe event: 0x%x\n", sub.type);
    656             break;
    657         }
    658     }
    659     if (i < array_sz) {
    660         for (--i; i >=0 ; i--) {
    661             memset(&sub, 0, sizeof(sub));
    662             sub.type = event_type[i];
    663             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    664             if (rc)
    665                 printf("Failed to unsubscribe event: 0x%x\n", sub.type);
    666         }
    667         eRet = OMX_ErrorNotImplemented;
    668     }
    669     return eRet;
    670 }
    671 
    672 
    673 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    674 {
    675     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    676     struct v4l2_event_subscription sub;
    677     int array_sz = sizeof(event_type)/sizeof(int);
    678     int i,rc;
    679     if (fd < 0) {
    680         printf("Invalid input: %d\n", fd);
    681         return OMX_ErrorBadParameter;
    682     }
    683 
    684     for (i = 0; i < array_sz; ++i) {
    685         memset(&sub, 0, sizeof(sub));
    686         sub.type = event_type[i];
    687         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    688         if (rc) {
    689             printf("Failed to unsubscribe event: 0x%x\n", sub.type);
    690             break;
    691         }
    692     }
    693     return eRet;
    694 }
    695 
    696 /* ======================================================================
    697    FUNCTION
    698    omx_vdec::~omx_vdec
    699 
    700    DESCRIPTION
    701    Destructor
    702 
    703    PARAMETERS
    704    None
    705 
    706    RETURN VALUE
    707    None.
    708    ========================================================================== */
    709 omx_vdec::~omx_vdec()
    710 {
    711     m_pmem_info = NULL;
    712     struct v4l2_decoder_cmd dec;
    713     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
    714     if (m_pipe_in) close(m_pipe_in);
    715     if (m_pipe_out) close(m_pipe_out);
    716     m_pipe_in = -1;
    717     m_pipe_out = -1;
    718     DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    719     if (msg_thread_created)
    720         pthread_join(msg_thread_id,NULL);
    721     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    722     dec.cmd = V4L2_DEC_CMD_STOP;
    723     if (drv_ctx.video_driver_fd >=0 ) {
    724         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
    725             DEBUG_PRINT_ERROR("\n STOP Command failed\n");
    726     }
    727     if (async_thread_created)
    728         pthread_join(async_thread_id,NULL);
    729     unsubscribe_to_events(drv_ctx.video_driver_fd);
    730     close(drv_ctx.video_driver_fd);
    731     pthread_mutex_destroy(&m_lock);
    732     pthread_mutex_destroy(&c_lock);
    733     pthread_mutex_destroy(&e_lock);
    734     sem_destroy(&m_cmd_lock);
    735     if (perf_flag) {
    736         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
    737         dec_time.end();
    738     }
    739     DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
    740 }
    741 
    742 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
    743 {
    744     struct v4l2_requestbuffers bufreq;
    745     int rc = 0;
    746     if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
    747         bufreq.memory = V4L2_MEMORY_USERPTR;
    748         bufreq.count = 0;
    749         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    750         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    751     } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
    752         bufreq.memory = V4L2_MEMORY_USERPTR;
    753         bufreq.count = 0;
    754         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    755         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    756     }
    757     return rc;
    758 }
    759 
    760 /* ======================================================================
    761    FUNCTION
    762    omx_vdec::OMXCntrlProcessMsgCb
    763 
    764    DESCRIPTION
    765    IL Client callbacks are generated through this routine. The decoder
    766    provides the thread context for this routine.
    767 
    768    PARAMETERS
    769    ctxt -- Context information related to the self.
    770    id   -- Event identifier. This could be any of the following:
    771    1. Command completion event
    772    2. Buffer done callback event
    773    3. Frame done callback event
    774 
    775    RETURN VALUE
    776    None.
    777 
    778    ========================================================================== */
    779 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
    780 {
    781     signed p1; // Parameter - 1
    782     signed p2; // Parameter - 2
    783     unsigned ident;
    784     unsigned qsize=0; // qsize
    785     omx_vdec *pThis = (omx_vdec *) ctxt;
    786 
    787     if (!pThis) {
    788         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out\n",
    789                 __func__);
    790         return;
    791     }
    792 
    793     // Protect the shared queue data structure
    794     do {
    795         /*Read the message id's from the queue*/
    796         pthread_mutex_lock(&pThis->m_lock);
    797         qsize = pThis->m_cmd_q.m_size;
    798         if (qsize) {
    799             pThis->m_cmd_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    800         }
    801 
    802         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
    803             qsize = pThis->m_ftb_q.m_size;
    804             if (qsize) {
    805                 pThis->m_ftb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    806             }
    807         }
    808 
    809         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
    810             qsize = pThis->m_etb_q.m_size;
    811             if (qsize) {
    812                 pThis->m_etb_q.pop_entry((unsigned *)&p1, (unsigned *)&p2, &ident);
    813             }
    814         }
    815         pthread_mutex_unlock(&pThis->m_lock);
    816 
    817         /*process message if we have one*/
    818         if (qsize > 0) {
    819             id = ident;
    820             switch (id) {
    821                 case OMX_COMPONENT_GENERATE_EVENT:
    822                     if (pThis->m_cb.EventHandler) {
    823                         switch (p1) {
    824                             case OMX_CommandStateSet:
    825                                 pThis->m_state = (OMX_STATETYPE) p2;
    826                                 DEBUG_PRINT_HIGH("\n OMX_CommandStateSet complete, m_state = %d",
    827                                         pThis->m_state);
    828                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    829                                         OMX_EventCmdComplete, p1, p2, NULL);
    830                                 break;
    831 
    832                             case OMX_EventError:
    833                                 if (p2 == OMX_StateInvalid) {
    834                                     DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
    835                                     pThis->m_state = (OMX_STATETYPE) p2;
    836                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    837                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    838                                 } else if (p2 == OMX_ErrorHardware) {
    839                                     pThis->omx_report_error();
    840                                 } else {
    841                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    842                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
    843                                 }
    844                                 break;
    845 
    846                             case OMX_CommandPortDisable:
    847                                 DEBUG_PRINT_HIGH("\n OMX_CommandPortDisable complete for port [%d]", p2);
    848                                 if (BITMASK_PRESENT(&pThis->m_flags,
    849                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
    850                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
    851                                     break;
    852                                 }
    853                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
    854                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    855                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
    856                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
    857                                         DEBUG_PRINT_HIGH("Failed to release output buffers\n");
    858                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
    859                                     pThis->in_reconfig = false;
    860                                     if (eRet !=  OMX_ErrorNone) {
    861                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
    862                                         pThis->omx_report_error();
    863                                         break;
    864                                     }
    865                                 }
    866                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    867                                         OMX_EventCmdComplete, p1, p2, NULL );
    868                                 break;
    869                             case OMX_CommandPortEnable:
    870                                 DEBUG_PRINT_HIGH("\n OMX_CommandPortEnable complete for port [%d]", p2);
    871                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    872                                         OMX_EventCmdComplete, p1, p2, NULL );
    873                                 break;
    874 
    875                             default:
    876                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    877                                         OMX_EventCmdComplete, p1, p2, NULL );
    878                                 break;
    879 
    880                         }
    881                     } else {
    882                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL\n", __func__);
    883                     }
    884                     break;
    885                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
    886                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
    887                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
    888                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
    889                         pThis->omx_report_error ();
    890                     }
    891                     break;
    892                 case OMX_COMPONENT_GENERATE_ETB:
    893                     if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    894                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
    895                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
    896                         pThis->omx_report_error ();
    897                     }
    898                     break;
    899 
    900                 case OMX_COMPONENT_GENERATE_FTB:
    901                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
    902                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
    903                         DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
    904                         pThis->omx_report_error ();
    905                     }
    906                     break;
    907 
    908                 case OMX_COMPONENT_GENERATE_COMMAND:
    909                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    910                             (OMX_U32)p2,(OMX_PTR)NULL);
    911                     break;
    912 
    913                 case OMX_COMPONENT_GENERATE_EBD:
    914 
    915                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
    916                         DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
    917                         pThis->omx_report_error ();
    918                     } else {
    919                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
    920                             pThis->m_inp_err_count++;
    921                             pThis->time_stamp_dts.remove_time_stamp(
    922                                     ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
    923                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
    924                                     ?true:false);
    925                         } else {
    926                             pThis->m_inp_err_count = 0;
    927                         }
    928                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
    929                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
    930                             DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
    931                             pThis->omx_report_error ();
    932                         }
    933                         if (pThis->m_inp_err_count >= MAX_INPUT_ERROR) {
    934                             DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
    935                             pThis->omx_report_error ();
    936                         }
    937                     }
    938                     break;
    939                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
    940                                             int64_t *timestamp = (int64_t *)p1;
    941                                             if (p1) {
    942                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
    943                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
    944                                                         ?true:false);
    945                                                 free(timestamp);
    946                                             }
    947                                         }
    948                                         break;
    949                 case OMX_COMPONENT_GENERATE_FBD:
    950                                         if (p2 != VDEC_S_SUCCESS) {
    951                                             DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
    952                                             pThis->omx_report_error ();
    953                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
    954                                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
    955                                             DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
    956                                             pThis->omx_report_error ();
    957                                         }
    958                                         break;
    959 
    960                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
    961                                         DEBUG_PRINT_HIGH("\n Driver flush i/p Port complete");
    962                                         if (!pThis->input_flush_progress) {
    963                                             DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
    964                                         } else {
    965                                             pThis->execute_input_flush();
    966                                             if (pThis->m_cb.EventHandler) {
    967                                                 if (p2 != VDEC_S_SUCCESS) {
    968                                                     DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
    969                                                     pThis->omx_report_error ();
    970                                                 } else {
    971                                                     /*Check if we need generate event for Flush done*/
    972                                                     if (BITMASK_PRESENT(&pThis->m_flags,
    973                                                                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
    974                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
    975                                                         DEBUG_PRINT_LOW("\n Input Flush completed - Notify Client");
    976                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    977                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
    978                                                                 OMX_CORE_INPUT_PORT_INDEX,NULL );
    979                                                     }
    980                                                     if (BITMASK_PRESENT(&pThis->m_flags,
    981                                                                 OMX_COMPONENT_IDLE_PENDING)) {
    982                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
    983                                                             DEBUG_PRINT_ERROR("\n Failed to call streamoff on OUTPUT Port \n");
    984                                                             pThis->omx_report_error ();
    985                                                         } else {
    986                                                             pThis->streaming[OUTPUT_PORT] = false;
    987                                                         }
    988                                                         if (!pThis->output_flush_progress) {
    989                                                             DEBUG_PRINT_LOW("\n Input flush done hence issue stop");
    990                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
    991                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
    992                                                         }
    993                                                     }
    994                                                 }
    995                                             } else {
    996                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
    997                                             }
    998                                         }
    999                                         break;
   1000 
   1001                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1002                                         DEBUG_PRINT_HIGH("\n Driver flush o/p Port complete");
   1003                                         if (!pThis->output_flush_progress) {
   1004                                             DEBUG_PRINT_HIGH("\n WARNING: Unexpected flush from driver");
   1005                                         } else {
   1006                                             pThis->execute_output_flush();
   1007                                             if (pThis->m_cb.EventHandler) {
   1008                                                 if (p2 != VDEC_S_SUCCESS) {
   1009                                                     DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1010                                                     pThis->omx_report_error ();
   1011                                                 } else {
   1012                                                     /*Check if we need generate event for Flush done*/
   1013                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1014                                                                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   1015                                                         DEBUG_PRINT_LOW("\n Notify Output Flush done");
   1016                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1017                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1018                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
   1019                                                                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   1020                                                     }
   1021                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1022                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1023                                                         DEBUG_PRINT_LOW("\n Internal flush complete");
   1024                                                         BITMASK_CLEAR (&pThis->m_flags,
   1025                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1026                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1027                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1028                                                             pThis->post_event(OMX_CommandPortDisable,
   1029                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1030                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1031                                                             BITMASK_CLEAR (&pThis->m_flags,
   1032                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1033 
   1034                                                         }
   1035                                                     }
   1036 
   1037                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1038                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1039                                                             DEBUG_PRINT_ERROR("\n Failed to call streamoff on CAPTURE Port \n");
   1040                                                             pThis->omx_report_error ();
   1041                                                             break;
   1042                                                         }
   1043                                                         pThis->streaming[CAPTURE_PORT] = false;
   1044                                                         if (!pThis->input_flush_progress) {
   1045                                                             DEBUG_PRINT_LOW("\n Output flush done hence issue stop");
   1046                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1047                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1048                                                         }
   1049                                                     }
   1050                                                 }
   1051                                             } else {
   1052                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1053                                             }
   1054                                         }
   1055                                         break;
   1056 
   1057                 case OMX_COMPONENT_GENERATE_START_DONE:
   1058                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1059 
   1060                                         if (pThis->m_cb.EventHandler) {
   1061                                             if (p2 != VDEC_S_SUCCESS) {
   1062                                                 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
   1063                                                 pThis->omx_report_error ();
   1064                                             } else {
   1065                                                 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
   1066                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1067                                                     DEBUG_PRINT_LOW("\n Move to executing");
   1068                                                     // Send the callback now
   1069                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1070                                                     pThis->m_state = OMX_StateExecuting;
   1071                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1072                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1073                                                             OMX_StateExecuting, NULL);
   1074                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1075                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1076                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1077                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1078                                                         DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
   1079                                                         pThis->omx_report_error ();
   1080                                                     }
   1081                                                 }
   1082                                             }
   1083                                         } else {
   1084                                             DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
   1085                                         }
   1086                                         break;
   1087 
   1088                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1089                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1090                                         if (pThis->m_cb.EventHandler) {
   1091                                             if (p2 != VDEC_S_SUCCESS) {
   1092                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1093                                                 pThis->omx_report_error ();
   1094                                             } else {
   1095                                                 pThis->complete_pending_buffer_done_cbs();
   1096                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1097                                                     DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1098                                                     //Send the callback now
   1099                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1100                                                     pThis->m_state = OMX_StatePause;
   1101                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1102                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1103                                                             OMX_StatePause, NULL);
   1104                                                 }
   1105                                             }
   1106                                         } else {
   1107                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1108                                         }
   1109 
   1110                                         break;
   1111 
   1112                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1113                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1114                                         if (pThis->m_cb.EventHandler) {
   1115                                             if (p2 != VDEC_S_SUCCESS) {
   1116                                                 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1117                                                 pThis->omx_report_error ();
   1118                                             } else {
   1119                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1120                                                     DEBUG_PRINT_LOW("\n Moving the decoder to execute state");
   1121                                                     // Send the callback now
   1122                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1123                                                     pThis->m_state = OMX_StateExecuting;
   1124                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1125                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1126                                                             OMX_StateExecuting,NULL);
   1127                                                 }
   1128                                             }
   1129                                         } else {
   1130                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1131                                         }
   1132 
   1133                                         break;
   1134 
   1135                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1136                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1137                                         if (pThis->m_cb.EventHandler) {
   1138                                             if (p2 != VDEC_S_SUCCESS) {
   1139                                                 DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1140                                                 pThis->omx_report_error ();
   1141                                             } else {
   1142                                                 pThis->complete_pending_buffer_done_cbs();
   1143                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1144                                                     DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1145                                                     // Send the callback now
   1146                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1147                                                     pThis->m_state = OMX_StateIdle;
   1148                                                     DEBUG_PRINT_LOW("\n Move to Idle State");
   1149                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1150                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1151                                                             OMX_StateIdle,NULL);
   1152                                                 }
   1153                                             }
   1154                                         } else {
   1155                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1156                                         }
   1157 
   1158                                         break;
   1159 
   1160                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1161                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
   1162 
   1163                                         if (p2 == OMX_IndexParamPortDefinition) {
   1164                                             pThis->in_reconfig = true;
   1165                                         }
   1166                                         if (pThis->m_cb.EventHandler) {
   1167                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1168                                                     OMX_EventPortSettingsChanged, p1, p2, NULL );
   1169                                         } else {
   1170                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1171                                         }
   1172 
   1173                                         if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) {
   1174                                             OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
   1175                                             OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
   1176                                             if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   1177                                                 format = OMX_InterlaceInterleaveFrameTopFieldFirst;
   1178                                             else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   1179                                                 format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   1180                                             else //unsupported interlace format; raise a error
   1181                                                 event = OMX_EventError;
   1182                                             if (pThis->m_cb.EventHandler) {
   1183                                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1184                                                         event, format, 0, NULL );
   1185                                             } else {
   1186                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1187                                             }
   1188                                         }
   1189                                         break;
   1190 
   1191                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1192                                         DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1193                                         if (pThis->m_cb.EventHandler) {
   1194                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1195                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1196                                         } else {
   1197                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1198                                         }
   1199                                         pThis->prev_ts = LLONG_MAX;
   1200                                         pThis->rst_prev_ts = true;
   1201                                         break;
   1202 
   1203                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1204                                         DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1205                                         pThis->omx_report_error ();
   1206                                         break;
   1207 
   1208                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1209                                         DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING\n");
   1210                                         pThis->omx_report_unsupported_setting();
   1211                                         break;
   1212 
   1213                 case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG: {
   1214                                             DEBUG_PRINT_HIGH("\n Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
   1215                                             if (pThis->m_cb.EventHandler) {
   1216                                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1217                                                         (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
   1218                                             } else {
   1219                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1220                                             }
   1221                                         }
   1222                 default:
   1223                                         break;
   1224             }
   1225         }
   1226         pthread_mutex_lock(&pThis->m_lock);
   1227         qsize = pThis->m_cmd_q.m_size;
   1228         if (pThis->m_state != OMX_StatePause)
   1229             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1230         pthread_mutex_unlock(&pThis->m_lock);
   1231     } while (qsize>0);
   1232 
   1233 }
   1234 
   1235 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1236 {
   1237     int format_changed = 0;
   1238     if ((height != drv_ctx.video_resolution.frame_height) ||
   1239             (width != drv_ctx.video_resolution.frame_width)) {
   1240         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)\n",
   1241                 width, drv_ctx.video_resolution.frame_width,
   1242                 height,drv_ctx.video_resolution.frame_height);
   1243         format_changed = 1;
   1244     }
   1245     drv_ctx.video_resolution.frame_height = height;
   1246     drv_ctx.video_resolution.frame_width = width;
   1247     drv_ctx.video_resolution.scan_lines = scan_lines;
   1248     drv_ctx.video_resolution.stride = stride;
   1249     rectangle.nLeft = 0;
   1250     rectangle.nTop = 0;
   1251     rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   1252     rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   1253     return format_changed;
   1254 }
   1255 
   1256 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1257 {
   1258     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1259                 OMX_MAX_STRINGNAME_SIZE) &&
   1260             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1261         m_decoder_capability.max_width = 1280;
   1262         m_decoder_capability.max_height = 720;
   1263         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1264     }
   1265 
   1266     if ((drv_ctx.video_resolution.frame_width *
   1267                 drv_ctx.video_resolution.frame_height >
   1268                 m_decoder_capability.max_width *
   1269                 m_decoder_capability.max_height) ||
   1270             (drv_ctx.video_resolution.frame_width*
   1271              drv_ctx.video_resolution.frame_height <
   1272              m_decoder_capability.min_width *
   1273              m_decoder_capability.min_height)) {
   1274         DEBUG_PRINT_ERROR(
   1275                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1276                 drv_ctx.video_resolution.frame_width,
   1277                 drv_ctx.video_resolution.frame_height,
   1278                 m_decoder_capability.min_width,
   1279                 m_decoder_capability.min_height,
   1280                 m_decoder_capability.max_width,
   1281                 m_decoder_capability.max_height);
   1282         return OMX_ErrorUnsupportedSetting;
   1283     }
   1284     DEBUG_PRINT_HIGH("\n video session supported\n");
   1285     return OMX_ErrorNone;
   1286 }
   1287 
   1288 /* ======================================================================
   1289    FUNCTION
   1290    omx_vdec::ComponentInit
   1291 
   1292    DESCRIPTION
   1293    Initialize the component.
   1294 
   1295    PARAMETERS
   1296    ctxt -- Context information related to the self.
   1297    id   -- Event identifier. This could be any of the following:
   1298    1. Command completion event
   1299    2. Buffer done callback event
   1300    3. Frame done callback event
   1301 
   1302    RETURN VALUE
   1303    None.
   1304 
   1305    ========================================================================== */
   1306 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   1307 {
   1308 
   1309     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1310     struct v4l2_fmtdesc fdesc;
   1311     struct v4l2_format fmt;
   1312     struct v4l2_requestbuffers bufreq;
   1313     struct v4l2_control control;
   1314     struct v4l2_frmsizeenum frmsize;
   1315     unsigned int   alignment = 0,buffer_size = 0;
   1316     int fds[2];
   1317     int r,ret=0;
   1318     bool codec_ambiguous = false;
   1319     OMX_STRING device_name = (OMX_STRING)"/dev/video/venus_dec";
   1320 
   1321     if (!strncmp(role, "OMX.qcom.video.decoder.avc.smoothstreaming",OMX_MAX_STRINGNAME_SIZE)) {
   1322         ALOGI("smooth streaming role");
   1323         mInSmoothstreamingMode = true;
   1324         role = "OMX.qcom.video.decoder.avc";
   1325     }
   1326     if (!strncmp(role, "OMX.qcom.video.decoder.avc.smoothstreaming.secure",OMX_MAX_STRINGNAME_SIZE)) {
   1327         ALOGI("secure smooth streaming role");
   1328         mInSmoothstreamingMode = true;
   1329         role = "OMX.qcom.video.decoder.avc.secure";
   1330     }
   1331 
   1332 #ifdef _ANDROID_
   1333     char platform_name[PROPERTY_VALUE_MAX];
   1334     property_get("ro.board.platform", platform_name, "0");
   1335     if (!strncmp(platform_name, "msm8610", 7)) {
   1336         device_name = (OMX_STRING)"/dev/video/q6_dec";
   1337     }
   1338 #endif
   1339 
   1340     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
   1341         struct v4l2_control control;
   1342         secure_mode = true;
   1343         arbitrary_bytes = false;
   1344         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   1345     }
   1346 
   1347     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   1348 
   1349     DEBUG_PRINT_HIGH("\n omx_vdec::component_init(): Open returned fd %d, errno %d",
   1350             drv_ctx.video_driver_fd, errno);
   1351 
   1352     if (drv_ctx.video_driver_fd == 0) {
   1353         DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again\n");
   1354         drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   1355         close(0);
   1356     }
   1357 
   1358     if (drv_ctx.video_driver_fd < 0) {
   1359         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d\n", errno);
   1360         return OMX_ErrorInsufficientResources;
   1361     }
   1362     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   1363     drv_ctx.frame_rate.fps_denominator = 1;
   1364 
   1365     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   1366     if (!ret) {
   1367         async_thread_created = true;
   1368         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   1369     }
   1370     if (ret) {
   1371         DEBUG_PRINT_ERROR("\n Failed to create async_message_thread \n");
   1372         async_thread_created = false;
   1373         return OMX_ErrorInsufficientResources;
   1374     }
   1375 
   1376 #ifdef INPUT_BUFFER_LOG
   1377     strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
   1378 #endif
   1379 #ifdef OUTPUT_BUFFER_LOG
   1380     outputBufferFile1 = fopen (outputfilename, "ab");
   1381 #endif
   1382 #ifdef OUTPUT_EXTRADATA_LOG
   1383     outputExtradataFile = fopen (ouputextradatafilename, "ab");
   1384 #endif
   1385 
   1386     // Copy the role information which provides the decoder kind
   1387     strlcpy(drv_ctx.kind,role,128);
   1388 
   1389     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   1390                 OMX_MAX_STRINGNAME_SIZE)) {
   1391         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   1392                 OMX_MAX_STRINGNAME_SIZE);
   1393         drv_ctx.timestamp_adjust = true;
   1394         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   1395         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   1396         output_capability=V4L2_PIX_FMT_MPEG4;
   1397         /*Initialize Start Code for MPEG4*/
   1398         codec_type_parse = CODEC_TYPE_MPEG4;
   1399         m_frame_parser.init_start_codes (codec_type_parse);
   1400 #ifdef INPUT_BUFFER_LOG
   1401         strcat(inputfilename, "m4v");
   1402 #endif
   1403     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   1404                 OMX_MAX_STRINGNAME_SIZE)) {
   1405         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   1406                 OMX_MAX_STRINGNAME_SIZE);
   1407         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   1408         output_capability = V4L2_PIX_FMT_MPEG2;
   1409         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   1410         /*Initialize Start Code for MPEG2*/
   1411         codec_type_parse = CODEC_TYPE_MPEG2;
   1412         m_frame_parser.init_start_codes (codec_type_parse);
   1413 #ifdef INPUT_BUFFER_LOG
   1414         strcat(inputfilename, "mpg");
   1415 #endif
   1416     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   1417                 OMX_MAX_STRINGNAME_SIZE)) {
   1418         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   1419         DEBUG_PRINT_LOW("\n H263 Decoder selected");
   1420         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   1421         eCompressionFormat = OMX_VIDEO_CodingH263;
   1422         output_capability = V4L2_PIX_FMT_H263;
   1423         codec_type_parse = CODEC_TYPE_H263;
   1424         m_frame_parser.init_start_codes (codec_type_parse);
   1425 #ifdef INPUT_BUFFER_LOG
   1426         strcat(inputfilename, "263");
   1427 #endif
   1428     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   1429                 OMX_MAX_STRINGNAME_SIZE)) {
   1430         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1431         DEBUG_PRINT_LOW ("\n DIVX 311 Decoder selected");
   1432         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   1433         output_capability = V4L2_PIX_FMT_DIVX_311;
   1434         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1435         codec_type_parse = CODEC_TYPE_DIVX;
   1436         m_frame_parser.init_start_codes (codec_type_parse);
   1437 
   1438         eRet = createDivxDrmContext();
   1439         if (eRet != OMX_ErrorNone) {
   1440             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1441             return eRet;
   1442         }
   1443     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   1444                 OMX_MAX_STRINGNAME_SIZE)) {
   1445         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1446         DEBUG_PRINT_ERROR ("\n DIVX 4 Decoder selected");
   1447         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   1448         output_capability = V4L2_PIX_FMT_DIVX;
   1449         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1450         codec_type_parse = CODEC_TYPE_DIVX;
   1451         codec_ambiguous = true;
   1452         m_frame_parser.init_start_codes (codec_type_parse);
   1453 
   1454         eRet = createDivxDrmContext();
   1455         if (eRet != OMX_ErrorNone) {
   1456             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1457             return eRet;
   1458         }
   1459     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   1460                 OMX_MAX_STRINGNAME_SIZE)) {
   1461         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1462         DEBUG_PRINT_ERROR ("\n DIVX 5/6 Decoder selected");
   1463         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   1464         output_capability = V4L2_PIX_FMT_DIVX;
   1465         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1466         codec_type_parse = CODEC_TYPE_DIVX;
   1467         codec_ambiguous = true;
   1468         m_frame_parser.init_start_codes (codec_type_parse);
   1469 
   1470         eRet = createDivxDrmContext();
   1471         if (eRet != OMX_ErrorNone) {
   1472             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1473             return eRet;
   1474         }
   1475 
   1476     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   1477                 OMX_MAX_STRINGNAME_SIZE)) {
   1478         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   1479         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   1480         output_capability=V4L2_PIX_FMT_H264;
   1481         eCompressionFormat = OMX_VIDEO_CodingAVC;
   1482         codec_type_parse = CODEC_TYPE_H264;
   1483         m_frame_parser.init_start_codes (codec_type_parse);
   1484         m_frame_parser.init_nal_length(nal_length);
   1485 #ifdef INPUT_BUFFER_LOG
   1486         strcat(inputfilename, "264");
   1487 #endif
   1488     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   1489                 OMX_MAX_STRINGNAME_SIZE)) {
   1490         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   1491         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   1492         eCompressionFormat = OMX_VIDEO_CodingWMV;
   1493         codec_type_parse = CODEC_TYPE_VC1;
   1494         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   1495         m_frame_parser.init_start_codes (codec_type_parse);
   1496 #ifdef INPUT_BUFFER_LOG
   1497         strcat(inputfilename, "vc1");
   1498 #endif
   1499     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   1500                 OMX_MAX_STRINGNAME_SIZE)) {
   1501         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   1502         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   1503         eCompressionFormat = OMX_VIDEO_CodingWMV;
   1504         codec_type_parse = CODEC_TYPE_VC1;
   1505         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   1506         m_frame_parser.init_start_codes (codec_type_parse);
   1507 #ifdef INPUT_BUFFER_LOG
   1508         strcat(inputfilename, "vc1");
   1509 #endif
   1510     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   1511                 OMX_MAX_STRINGNAME_SIZE)) {
   1512         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   1513         output_capability=V4L2_PIX_FMT_VP8;
   1514         eCompressionFormat = OMX_VIDEO_CodingVPX;
   1515         codec_type_parse = CODEC_TYPE_VP8;
   1516         arbitrary_bytes = false;
   1517 #ifdef INPUT_BUFFER_LOG
   1518         strcat(inputfilename, "ivf");
   1519 #endif
   1520 
   1521     } else {
   1522         DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
   1523         eRet = OMX_ErrorInvalidComponentName;
   1524     }
   1525 #ifdef INPUT_BUFFER_LOG
   1526     inputBufferFile1 = fopen (inputfilename, "ab");
   1527     if (output_capability == V4L2_PIX_FMT_VP8) {
   1528         struct ivf_file_header {
   1529             OMX_U8 signature[4]; //='DKIF';
   1530             OMX_U8 version         ; //= 0;
   1531             OMX_U8 headersize      ; //= 32;
   1532             OMX_U32 FourCC;
   1533             OMX_U8 width;
   1534             OMX_U8 height;
   1535             OMX_U32 rate;
   1536             OMX_U32 scale;
   1537             OMX_U32 length;
   1538             OMX_U8 unused[4];
   1539         } file_header;
   1540         memset((void *)&file_header,0,sizeof(file_header));
   1541         file_header.signature[0] = 'D';
   1542         file_header.signature[1] = 'K';
   1543         file_header.signature[2] = 'I';
   1544         file_header.signature[3] = 'F';
   1545         file_header.version = 0;
   1546         file_header.headersize = 32;
   1547         file_header.FourCC = 0x30385056;
   1548         if (inputBufferFile1) {
   1549             fwrite((const char *)&file_header,
   1550                     sizeof(file_header),1,inputBufferFile1);
   1551         }
   1552     }
   1553 #endif
   1554     if (eRet == OMX_ErrorNone) {
   1555 
   1556         drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   1557         OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
   1558             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   1559         if (!client_buffers.set_color_format(dest_color_format)) {
   1560             DEBUG_PRINT_ERROR("\n Setting color format failed");
   1561             eRet = OMX_ErrorInsufficientResources;
   1562         }
   1563 
   1564         capture_capability= V4L2_PIX_FMT_NV12;
   1565 
   1566         struct v4l2_capability cap;
   1567         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   1568         if (ret) {
   1569             DEBUG_PRINT_ERROR("Failed to query capabilities\n");
   1570             /*TODO: How to handle this case */
   1571         } else {
   1572             DEBUG_PRINT_HIGH("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   1573                     " version = %d, capabilities = %x\n", cap.driver, cap.card,
   1574                     cap.bus_info, cap.version, cap.capabilities);
   1575         }
   1576         ret=0;
   1577         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1578         fdesc.index=0;
   1579         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1580             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
   1581                     fdesc.pixelformat, fdesc.flags);
   1582             fdesc.index++;
   1583         }
   1584         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1585         fdesc.index=0;
   1586         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1587 
   1588             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x\n", fdesc.description,
   1589                     fdesc.pixelformat, fdesc.flags);
   1590             fdesc.index++;
   1591         }
   1592         update_resolution(320, 240, 320, 240);
   1593         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1594         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1595         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1596         fmt.fmt.pix_mp.pixelformat = output_capability;
   1597         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1598         if (ret) {
   1599             /*TODO: How to handle this case */
   1600             DEBUG_PRINT_ERROR("Failed to set format on output port\n");
   1601             return OMX_ErrorInsufficientResources;
   1602         }
   1603         DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
   1604         if (codec_ambiguous) {
   1605             if (output_capability == V4L2_PIX_FMT_DIVX) {
   1606                 struct v4l2_control divx_ctrl;
   1607 
   1608                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   1609                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   1610                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   1611                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   1612                 } else {
   1613                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   1614                 }
   1615 
   1616                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   1617                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   1618                 if (ret) {
   1619                     DEBUG_PRINT_ERROR("Failed to set divx version\n");
   1620                 }
   1621             } else {
   1622                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   1623             }
   1624         }
   1625 
   1626         //Get the hardware capabilities
   1627         memset((void *)&frmsize,0,sizeof(frmsize));
   1628         frmsize.index = 0;
   1629         frmsize.pixel_format = output_capability;
   1630         ret = ioctl(drv_ctx.video_driver_fd,
   1631                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   1632         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   1633             DEBUG_PRINT_ERROR("Failed to get framesizes\n");
   1634             return OMX_ErrorHardware;
   1635         }
   1636 
   1637         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   1638             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   1639             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   1640             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   1641             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   1642         }
   1643 
   1644         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1645         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1646         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1647         fmt.fmt.pix_mp.pixelformat = capture_capability;
   1648         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1649         if (ret) {
   1650             /*TODO: How to handle this case */
   1651             DEBUG_PRINT_ERROR("Failed to set format on capture port\n");
   1652         }
   1653         DEBUG_PRINT_HIGH("\n Set Format was successful \n ");
   1654         if (secure_mode) {
   1655             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   1656             control.value = 1;
   1657             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d\n", ret);
   1658             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   1659             if (ret) {
   1660                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d\n", ret);
   1661                 return OMX_ErrorInsufficientResources;
   1662             }
   1663         }
   1664 
   1665         /*Get the Buffer requirements for input and output ports*/
   1666         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   1667         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   1668         if (secure_mode) {
   1669             drv_ctx.op_buf.alignment=SZ_1M;
   1670             drv_ctx.ip_buf.alignment=SZ_1M;
   1671         } else {
   1672             drv_ctx.op_buf.alignment=SZ_4K;
   1673             drv_ctx.ip_buf.alignment=SZ_4K;
   1674         }
   1675         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   1676         drv_ctx.extradata = 0;
   1677         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   1678         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   1679         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   1680         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1681         drv_ctx.idr_only_decoding = 0;
   1682 
   1683         m_state = OMX_StateLoaded;
   1684 #ifdef DEFAULT_EXTRADATA
   1685         if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   1686             OMX_MAX_STRINGNAME_SIZE)) {
   1687             if (eRet == OMX_ErrorNone && !secure_mode)
   1688                 enable_extradata(DEFAULT_EXTRADATA, true, true);
   1689         }
   1690 #endif
   1691         if (mInSmoothstreamingMode) {
   1692             control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   1693             control.value = 1;
   1694             DEBUG_PRINT_ERROR("Enabling smooth streaming!\n");
   1695             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   1696                 DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming");
   1697             }
   1698         }
   1699         eRet=get_buffer_req(&drv_ctx.ip_buf);
   1700         DEBUG_PRINT_HIGH("Input Buffer Size =%d \n ",drv_ctx.ip_buf.buffer_size);
   1701         get_buffer_req(&drv_ctx.op_buf);
   1702         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   1703             if (m_frame_parser.mutils == NULL) {
   1704                 m_frame_parser.mutils = new H264_Utils();
   1705 
   1706                 if (m_frame_parser.mutils == NULL) {
   1707                     DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
   1708                     eRet = OMX_ErrorInsufficientResources;
   1709                 } else {
   1710                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   1711                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   1712                     h264_scratch.nFilledLen = 0;
   1713                     h264_scratch.nOffset = 0;
   1714 
   1715                     if (h264_scratch.pBuffer == NULL) {
   1716                         DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
   1717                         return OMX_ErrorInsufficientResources;
   1718                     }
   1719                     m_frame_parser.mutils->initialize_frame_checking_environment();
   1720                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   1721                 }
   1722             }
   1723 
   1724             h264_parser = new h264_stream_parser();
   1725             if (!h264_parser) {
   1726                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   1727                 eRet = OMX_ErrorInsufficientResources;
   1728             }
   1729         }
   1730 
   1731         if (pipe(fds)) {
   1732             DEBUG_PRINT_ERROR("pipe creation failed\n");
   1733             eRet = OMX_ErrorInsufficientResources;
   1734         } else {
   1735             int temp1[2];
   1736             if (fds[0] == 0 || fds[1] == 0) {
   1737                 if (pipe (temp1)) {
   1738                     DEBUG_PRINT_ERROR("pipe creation failed\n");
   1739                     return OMX_ErrorInsufficientResources;
   1740                 }
   1741                 //close (fds[0]);
   1742                 //close (fds[1]);
   1743                 fds[0] = temp1 [0];
   1744                 fds[1] = temp1 [1];
   1745             }
   1746             m_pipe_in = fds[0];
   1747             m_pipe_out = fds[1];
   1748             msg_thread_created = true;
   1749             r = pthread_create(&msg_thread_id,0,message_thread,this);
   1750 
   1751             if (r < 0) {
   1752                 DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
   1753                 msg_thread_created = false;
   1754                 eRet = OMX_ErrorInsufficientResources;
   1755             }
   1756         }
   1757     }
   1758 
   1759     if (eRet != OMX_ErrorNone) {
   1760         DEBUG_PRINT_ERROR("\n Component Init Failed");
   1761     } else {
   1762         DEBUG_PRINT_HIGH("\n omx_vdec::component_init() success");
   1763     }
   1764     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   1765     return eRet;
   1766 }
   1767 
   1768 /* ======================================================================
   1769    FUNCTION
   1770    omx_vdec::GetComponentVersion
   1771 
   1772    DESCRIPTION
   1773    Returns the component version.
   1774 
   1775    PARAMETERS
   1776    TBD.
   1777 
   1778    RETURN VALUE
   1779    OMX_ErrorNone.
   1780 
   1781    ========================================================================== */
   1782 OMX_ERRORTYPE  omx_vdec::get_component_version
   1783 (
   1784  OMX_IN OMX_HANDLETYPE hComp,
   1785  OMX_OUT OMX_STRING componentName,
   1786  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   1787  OMX_OUT OMX_VERSIONTYPE* specVersion,
   1788  OMX_OUT OMX_UUIDTYPE* componentUUID
   1789  )
   1790 {
   1791     if (m_state == OMX_StateInvalid) {
   1792         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State\n");
   1793         return OMX_ErrorInvalidState;
   1794     }
   1795     /* TBD -- Return the proper version */
   1796     if (specVersion) {
   1797         specVersion->nVersion = OMX_SPEC_VERSION;
   1798     }
   1799     return OMX_ErrorNone;
   1800 }
   1801 /* ======================================================================
   1802    FUNCTION
   1803    omx_vdec::SendCommand
   1804 
   1805    DESCRIPTION
   1806    Returns zero if all the buffers released..
   1807 
   1808    PARAMETERS
   1809    None.
   1810 
   1811    RETURN VALUE
   1812    true/false
   1813 
   1814    ========================================================================== */
   1815 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   1816         OMX_IN OMX_COMMANDTYPE cmd,
   1817         OMX_IN OMX_U32 param1,
   1818         OMX_IN OMX_PTR cmdData
   1819         )
   1820 {
   1821     DEBUG_PRINT_LOW("\n send_command: Recieved a Command from Client");
   1822     if (m_state == OMX_StateInvalid) {
   1823         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
   1824         return OMX_ErrorInvalidState;
   1825     }
   1826     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   1827             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   1828         DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
   1829                 "to invalid port: %lu", param1);
   1830         return OMX_ErrorBadPortIndex;
   1831     }
   1832     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   1833     sem_wait(&m_cmd_lock);
   1834     DEBUG_PRINT_LOW("\n send_command: Command Processed\n");
   1835     return OMX_ErrorNone;
   1836 }
   1837 
   1838 /* ======================================================================
   1839    FUNCTION
   1840    omx_vdec::SendCommand
   1841 
   1842    DESCRIPTION
   1843    Returns zero if all the buffers released..
   1844 
   1845    PARAMETERS
   1846    None.
   1847 
   1848    RETURN VALUE
   1849    true/false
   1850 
   1851    ========================================================================== */
   1852 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   1853         OMX_IN OMX_COMMANDTYPE cmd,
   1854         OMX_IN OMX_U32 param1,
   1855         OMX_IN OMX_PTR cmdData
   1856         )
   1857 {
   1858     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1859     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   1860     int bFlag = 1,sem_posted = 0,ret=0;
   1861 
   1862     DEBUG_PRINT_LOW("\n send_command_proxy(): cmd = %d", cmd);
   1863     DEBUG_PRINT_HIGH("\n send_command_proxy(): Current State %d, Expected State %d",
   1864             m_state, eState);
   1865 
   1866     if (cmd == OMX_CommandStateSet) {
   1867         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandStateSet issued");
   1868         DEBUG_PRINT_HIGH("\n Current State %d, Expected State %d", m_state, eState);
   1869         /***************************/
   1870         /* Current State is Loaded */
   1871         /***************************/
   1872         if (m_state == OMX_StateLoaded) {
   1873             if (eState == OMX_StateIdle) {
   1874                 //if all buffers are allocated or all ports disabled
   1875                 if (allocate_done() ||
   1876                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   1877                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle\n");
   1878                 } else {
   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                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded\n");
   1888                 post_event(OMX_EventError,OMX_ErrorSameState,\
   1889                         OMX_COMPONENT_GENERATE_EVENT);
   1890                 eRet = OMX_ErrorSameState;
   1891             }
   1892             /* Requesting transition from Loaded to WaitForResources */
   1893             else if (eState == OMX_StateWaitForResources) {
   1894                 /* Since error is None , we will post an event
   1895                    at the end of this function definition */
   1896                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources\n");
   1897             }
   1898             /* Requesting transition from Loaded to Executing */
   1899             else if (eState == OMX_StateExecuting) {
   1900                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
   1901                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1902                         OMX_COMPONENT_GENERATE_EVENT);
   1903                 eRet = OMX_ErrorIncorrectStateTransition;
   1904             }
   1905             /* Requesting transition from Loaded to Pause */
   1906             else if (eState == OMX_StatePause) {
   1907                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
   1908                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1909                         OMX_COMPONENT_GENERATE_EVENT);
   1910                 eRet = OMX_ErrorIncorrectStateTransition;
   1911             }
   1912             /* Requesting transition from Loaded to Invalid */
   1913             else if (eState == OMX_StateInvalid) {
   1914                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
   1915                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1916                 eRet = OMX_ErrorInvalidState;
   1917             } else {
   1918                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
   1919                         eState);
   1920                 eRet = OMX_ErrorBadParameter;
   1921             }
   1922         }
   1923 
   1924         /***************************/
   1925         /* Current State is IDLE */
   1926         /***************************/
   1927         else if (m_state == OMX_StateIdle) {
   1928             if (eState == OMX_StateLoaded) {
   1929                 if (release_done()) {
   1930                     /*
   1931                        Since error is None , we will post an event at the end
   1932                        of this function definition
   1933                      */
   1934                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded\n");
   1935                 } else {
   1936                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending\n");
   1937                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   1938                     // Skip the event notification
   1939                     bFlag = 0;
   1940                 }
   1941             }
   1942             /* Requesting transition from Idle to Executing */
   1943             else if (eState == OMX_StateExecuting) {
   1944                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   1945                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   1946                 bFlag = 1;
   1947                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   1948                 m_state=OMX_StateExecuting;
   1949                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful\n");
   1950             }
   1951             /* Requesting transition from Idle to Idle */
   1952             else if (eState == OMX_StateIdle) {
   1953                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
   1954                 post_event(OMX_EventError,OMX_ErrorSameState,\
   1955                         OMX_COMPONENT_GENERATE_EVENT);
   1956                 eRet = OMX_ErrorSameState;
   1957             }
   1958             /* Requesting transition from Idle to WaitForResources */
   1959             else if (eState == OMX_StateWaitForResources) {
   1960                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
   1961                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   1962                         OMX_COMPONENT_GENERATE_EVENT);
   1963                 eRet = OMX_ErrorIncorrectStateTransition;
   1964             }
   1965             /* Requesting transition from Idle to Pause */
   1966             else if (eState == OMX_StatePause) {
   1967                 /*To pause the Video core we need to start the driver*/
   1968                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   1969                       NULL) < */0) {
   1970                     DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
   1971                     omx_report_error ();
   1972                     eRet = OMX_ErrorHardware;
   1973                 } else {
   1974                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   1975                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause\n");
   1976                     bFlag = 0;
   1977                 }
   1978             }
   1979             /* Requesting transition from Idle to Invalid */
   1980             else if (eState == OMX_StateInvalid) {
   1981                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
   1982                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   1983                 eRet = OMX_ErrorInvalidState;
   1984             } else {
   1985                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
   1986                 eRet = OMX_ErrorBadParameter;
   1987             }
   1988         }
   1989 
   1990         /******************************/
   1991         /* Current State is Executing */
   1992         /******************************/
   1993         else if (m_state == OMX_StateExecuting) {
   1994             DEBUG_PRINT_LOW("\n Command Recieved in OMX_StateExecuting");
   1995             /* Requesting transition from Executing to Idle */
   1996             if (eState == OMX_StateIdle) {
   1997                 /* Since error is None , we will post an event
   1998                    at the end of this function definition
   1999                  */
   2000                 DEBUG_PRINT_LOW("\n send_command_proxy(): Executing --> Idle \n");
   2001                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2002                 if (!sem_posted) {
   2003                     sem_posted = 1;
   2004                     sem_post (&m_cmd_lock);
   2005                     execute_omx_flush(OMX_ALL);
   2006                 }
   2007                 bFlag = 0;
   2008             }
   2009             /* Requesting transition from Executing to Paused */
   2010             else if (eState == OMX_StatePause) {
   2011                 DEBUG_PRINT_LOW("\n PAUSE Command Issued");
   2012                 m_state = OMX_StatePause;
   2013                 bFlag = 1;
   2014             }
   2015             /* Requesting transition from Executing to Loaded */
   2016             else if (eState == OMX_StateLoaded) {
   2017                 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
   2018                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2019                         OMX_COMPONENT_GENERATE_EVENT);
   2020                 eRet = OMX_ErrorIncorrectStateTransition;
   2021             }
   2022             /* Requesting transition from Executing to WaitForResources */
   2023             else if (eState == OMX_StateWaitForResources) {
   2024                 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
   2025                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2026                         OMX_COMPONENT_GENERATE_EVENT);
   2027                 eRet = OMX_ErrorIncorrectStateTransition;
   2028             }
   2029             /* Requesting transition from Executing to Executing */
   2030             else if (eState == OMX_StateExecuting) {
   2031                 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
   2032                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2033                         OMX_COMPONENT_GENERATE_EVENT);
   2034                 eRet = OMX_ErrorSameState;
   2035             }
   2036             /* Requesting transition from Executing to Invalid */
   2037             else if (eState == OMX_StateInvalid) {
   2038                 DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
   2039                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2040                 eRet = OMX_ErrorInvalidState;
   2041             } else {
   2042                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
   2043                 eRet = OMX_ErrorBadParameter;
   2044             }
   2045         }
   2046         /***************************/
   2047         /* Current State is Pause  */
   2048         /***************************/
   2049         else if (m_state == OMX_StatePause) {
   2050             /* Requesting transition from Pause to Executing */
   2051             if (eState == OMX_StateExecuting) {
   2052                 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
   2053                 m_state = OMX_StateExecuting;
   2054                 bFlag = 1;
   2055             }
   2056             /* Requesting transition from Pause to Idle */
   2057             else if (eState == OMX_StateIdle) {
   2058                 /* Since error is None , we will post an event
   2059                    at the end of this function definition */
   2060                 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
   2061                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2062                 if (!sem_posted) {
   2063                     sem_posted = 1;
   2064                     sem_post (&m_cmd_lock);
   2065                     execute_omx_flush(OMX_ALL);
   2066                 }
   2067                 bFlag = 0;
   2068             }
   2069             /* Requesting transition from Pause to loaded */
   2070             else if (eState == OMX_StateLoaded) {
   2071                 DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
   2072                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2073                         OMX_COMPONENT_GENERATE_EVENT);
   2074                 eRet = OMX_ErrorIncorrectStateTransition;
   2075             }
   2076             /* Requesting transition from Pause to WaitForResources */
   2077             else if (eState == OMX_StateWaitForResources) {
   2078                 DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
   2079                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2080                         OMX_COMPONENT_GENERATE_EVENT);
   2081                 eRet = OMX_ErrorIncorrectStateTransition;
   2082             }
   2083             /* Requesting transition from Pause to Pause */
   2084             else if (eState == OMX_StatePause) {
   2085                 DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
   2086                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2087                         OMX_COMPONENT_GENERATE_EVENT);
   2088                 eRet = OMX_ErrorSameState;
   2089             }
   2090             /* Requesting transition from Pause to Invalid */
   2091             else if (eState == OMX_StateInvalid) {
   2092                 DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
   2093                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2094                 eRet = OMX_ErrorInvalidState;
   2095             } else {
   2096                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
   2097                 eRet = OMX_ErrorBadParameter;
   2098             }
   2099         }
   2100         /***************************/
   2101         /* Current State is WaitForResources  */
   2102         /***************************/
   2103         else if (m_state == OMX_StateWaitForResources) {
   2104             /* Requesting transition from WaitForResources to Loaded */
   2105             if (eState == OMX_StateLoaded) {
   2106                 /* Since error is None , we will post an event
   2107                    at the end of this function definition */
   2108                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded\n");
   2109             }
   2110             /* Requesting transition from WaitForResources to WaitForResources */
   2111             else if (eState == OMX_StateWaitForResources) {
   2112                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
   2113                 post_event(OMX_EventError,OMX_ErrorSameState,
   2114                         OMX_COMPONENT_GENERATE_EVENT);
   2115                 eRet = OMX_ErrorSameState;
   2116             }
   2117             /* Requesting transition from WaitForResources to Executing */
   2118             else if (eState == OMX_StateExecuting) {
   2119                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
   2120                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2121                         OMX_COMPONENT_GENERATE_EVENT);
   2122                 eRet = OMX_ErrorIncorrectStateTransition;
   2123             }
   2124             /* Requesting transition from WaitForResources to Pause */
   2125             else if (eState == OMX_StatePause) {
   2126                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
   2127                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2128                         OMX_COMPONENT_GENERATE_EVENT);
   2129                 eRet = OMX_ErrorIncorrectStateTransition;
   2130             }
   2131             /* Requesting transition from WaitForResources to Invalid */
   2132             else if (eState == OMX_StateInvalid) {
   2133                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
   2134                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2135                 eRet = OMX_ErrorInvalidState;
   2136             }
   2137             /* Requesting transition from WaitForResources to Loaded -
   2138                is NOT tested by Khronos TS */
   2139 
   2140         } else {
   2141             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
   2142             eRet = OMX_ErrorBadParameter;
   2143         }
   2144     }
   2145     /********************************/
   2146     /* Current State is Invalid */
   2147     /*******************************/
   2148     else if (m_state == OMX_StateInvalid) {
   2149         /* State Transition from Inavlid to any state */
   2150         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   2151                     || OMX_StateIdle || OMX_StateExecuting
   2152                     || OMX_StatePause || OMX_StateInvalid)) {
   2153             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
   2154             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   2155                     OMX_COMPONENT_GENERATE_EVENT);
   2156             eRet = OMX_ErrorInvalidState;
   2157         }
   2158     } else if (cmd == OMX_CommandFlush) {
   2159         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandFlush issued"
   2160                 "with param1: %lu", param1);
   2161         send_codec_config();
   2162         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2163             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   2164         }
   2165         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2166             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   2167         }
   2168         if (!sem_posted) {
   2169             sem_posted = 1;
   2170             DEBUG_PRINT_LOW("\n Set the Semaphore");
   2171             sem_post (&m_cmd_lock);
   2172             execute_omx_flush(param1);
   2173         }
   2174         bFlag = 0;
   2175     } else if ( cmd == OMX_CommandPortEnable) {
   2176         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortEnable issued"
   2177                 "with param1: %lu", param1);
   2178         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2179             m_inp_bEnabled = OMX_TRUE;
   2180 
   2181             if ( (m_state == OMX_StateLoaded &&
   2182                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2183                     || allocate_input_done()) {
   2184                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   2185                         OMX_COMPONENT_GENERATE_EVENT);
   2186             } else {
   2187                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   2188                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2189                 // Skip the event notification
   2190                 bFlag = 0;
   2191             }
   2192         }
   2193         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   2194             DEBUG_PRINT_LOW("\n Enable output Port command recieved");
   2195             m_out_bEnabled = OMX_TRUE;
   2196 
   2197             if ( (m_state == OMX_StateLoaded &&
   2198                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2199                     || (allocate_output_done())) {
   2200                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   2201                         OMX_COMPONENT_GENERATE_EVENT);
   2202 
   2203             } else {
   2204                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending\n");
   2205                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2206                 // Skip the event notification
   2207                 bFlag = 0;
   2208             }
   2209         }
   2210     } else if (cmd == OMX_CommandPortDisable) {
   2211         DEBUG_PRINT_HIGH("\n send_command_proxy(): OMX_CommandPortDisable issued"
   2212                 "with param1: %lu", param1);
   2213         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2214             codec_config_flag = false;
   2215             m_inp_bEnabled = OMX_FALSE;
   2216             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2217                     && release_input_done()) {
   2218                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   2219                         OMX_COMPONENT_GENERATE_EVENT);
   2220             } else {
   2221                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   2222                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   2223                     if (!sem_posted) {
   2224                         sem_posted = 1;
   2225                         sem_post (&m_cmd_lock);
   2226                     }
   2227                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   2228                 }
   2229 
   2230                 // Skip the event notification
   2231                 bFlag = 0;
   2232             }
   2233         }
   2234         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   2235             m_out_bEnabled = OMX_FALSE;
   2236             DEBUG_PRINT_LOW("\n Disable output Port command recieved");
   2237             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2238                     && release_output_done()) {
   2239                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   2240                         OMX_COMPONENT_GENERATE_EVENT);
   2241             } else {
   2242                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   2243                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   2244                     if (!sem_posted) {
   2245                         sem_posted = 1;
   2246                         sem_post (&m_cmd_lock);
   2247                     }
   2248                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   2249                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   2250                 }
   2251                 // Skip the event notification
   2252                 bFlag = 0;
   2253 
   2254             }
   2255         }
   2256     } else {
   2257         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
   2258         eRet = OMX_ErrorNotImplemented;
   2259     }
   2260     if (eRet == OMX_ErrorNone && bFlag) {
   2261         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   2262     }
   2263     if (!sem_posted) {
   2264         sem_post(&m_cmd_lock);
   2265     }
   2266 
   2267     return eRet;
   2268 }
   2269 
   2270 /* ======================================================================
   2271    FUNCTION
   2272    omx_vdec::ExecuteOmxFlush
   2273 
   2274    DESCRIPTION
   2275    Executes the OMX flush.
   2276 
   2277    PARAMETERS
   2278    flushtype - input flush(1)/output flush(0)/ both.
   2279 
   2280    RETURN VALUE
   2281    true/false
   2282 
   2283    ========================================================================== */
   2284 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   2285 {
   2286     bool bRet = false;
   2287     struct v4l2_plane plane;
   2288     struct v4l2_buffer v4l2_buf;
   2289     struct v4l2_decoder_cmd dec;
   2290     DEBUG_PRINT_LOW("in %s, flushing %d", __func__, flushType);
   2291     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   2292     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   2293 
   2294     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   2295 
   2296     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   2297         output_flush_progress = true;
   2298         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   2299     } else {
   2300         /* XXX: The driver/hardware does not support flushing of individual ports
   2301          * in all states. So we pretty much need to flush both ports internally,
   2302          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   2303          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   2304          * we automatically omit sending the FLUSH done for the "opposite" port. */
   2305         input_flush_progress = true;
   2306         output_flush_progress = true;
   2307         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   2308     }
   2309 
   2310     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   2311         DEBUG_PRINT_ERROR("\n Flush Port (%lu) Failed ", flushType);
   2312         bRet = false;
   2313     }
   2314 
   2315     return bRet;
   2316 }
   2317 /*=========================================================================
   2318 FUNCTION : execute_output_flush
   2319 
   2320 DESCRIPTION
   2321 Executes the OMX flush at OUTPUT PORT.
   2322 
   2323 PARAMETERS
   2324 None.
   2325 
   2326 RETURN VALUE
   2327 true/false
   2328 ==========================================================================*/
   2329 bool omx_vdec::execute_output_flush()
   2330 {
   2331     unsigned      p1 = 0; // Parameter - 1
   2332     unsigned      p2 = 0; // Parameter - 2
   2333     unsigned      ident = 0;
   2334     bool bRet = true;
   2335 
   2336     /*Generate FBD for all Buffers in the FTBq*/
   2337     pthread_mutex_lock(&m_lock);
   2338     DEBUG_PRINT_LOW("\n Initiate Output Flush");
   2339     while (m_ftb_q.m_size) {
   2340         DEBUG_PRINT_LOW("\n Buffer queue size %d pending buf cnt %d",
   2341                 m_ftb_q.m_size,pending_output_buffers);
   2342         m_ftb_q.pop_entry(&p1,&p2,&ident);
   2343         DEBUG_PRINT_LOW("\n ID(%x) P1(%x) P2(%x)", ident, p1, p2);
   2344         if (ident == m_fill_output_msg ) {
   2345             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   2346         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   2347             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   2348         }
   2349     }
   2350     pthread_mutex_unlock(&m_lock);
   2351     output_flush_progress = false;
   2352 
   2353     if (arbitrary_bytes) {
   2354         prev_ts = LLONG_MAX;
   2355         rst_prev_ts = true;
   2356     }
   2357     DEBUG_PRINT_HIGH("\n OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   2358     return bRet;
   2359 }
   2360 /*=========================================================================
   2361 FUNCTION : execute_input_flush
   2362 
   2363 DESCRIPTION
   2364 Executes the OMX flush at INPUT PORT.
   2365 
   2366 PARAMETERS
   2367 None.
   2368 
   2369 RETURN VALUE
   2370 true/false
   2371 ==========================================================================*/
   2372 bool omx_vdec::execute_input_flush()
   2373 {
   2374     unsigned       i =0;
   2375     unsigned      p1 = 0; // Parameter - 1
   2376     unsigned      p2 = 0; // Parameter - 2
   2377     unsigned      ident = 0;
   2378     bool bRet = true;
   2379 
   2380     /*Generate EBD for all Buffers in the ETBq*/
   2381     DEBUG_PRINT_LOW("\n Initiate Input Flush \n");
   2382 
   2383     pthread_mutex_lock(&m_lock);
   2384     DEBUG_PRINT_LOW("\n Check if the Queue is empty \n");
   2385     while (m_etb_q.m_size) {
   2386         m_etb_q.pop_entry(&p1,&p2,&ident);
   2387 
   2388         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   2389             DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   2390             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   2391         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   2392             pending_input_buffers++;
   2393             DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   2394                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   2395             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   2396         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   2397             DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   2398                     (OMX_BUFFERHEADERTYPE *)p1);
   2399             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   2400         }
   2401     }
   2402     time_stamp_dts.flush_timestamp();
   2403     /*Check if Heap Buffers are to be flushed*/
   2404     if (arbitrary_bytes && !(codec_config_flag)) {
   2405         DEBUG_PRINT_LOW("\n Reset all the variables before flusing");
   2406         h264_scratch.nFilledLen = 0;
   2407         nal_count = 0;
   2408         look_ahead_nal = false;
   2409         frame_count = 0;
   2410         h264_last_au_ts = LLONG_MAX;
   2411         h264_last_au_flags = 0;
   2412         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   2413         m_demux_entries = 0;
   2414         DEBUG_PRINT_LOW("\n Initialize parser");
   2415         if (m_frame_parser.mutils) {
   2416             m_frame_parser.mutils->initialize_frame_checking_environment();
   2417         }
   2418 
   2419         while (m_input_pending_q.m_size) {
   2420             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   2421             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   2422         }
   2423 
   2424         if (psource_frame) {
   2425             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   2426             psource_frame = NULL;
   2427         }
   2428 
   2429         if (pdest_frame) {
   2430             pdest_frame->nFilledLen = 0;
   2431             m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned int)NULL,
   2432                     (unsigned int)NULL);
   2433             pdest_frame = NULL;
   2434         }
   2435         m_frame_parser.flush();
   2436     } else if (codec_config_flag) {
   2437         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   2438                 "is not sent to the driver yet");
   2439     }
   2440     pthread_mutex_unlock(&m_lock);
   2441     input_flush_progress = false;
   2442     if (!arbitrary_bytes) {
   2443         prev_ts = LLONG_MAX;
   2444         rst_prev_ts = true;
   2445     }
   2446 #ifdef _ANDROID_
   2447     if (m_debug_timestamp) {
   2448         m_timestamp_list.reset_ts_list();
   2449     }
   2450 #endif
   2451     DEBUG_PRINT_HIGH("\n OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   2452     return bRet;
   2453 }
   2454 
   2455 
   2456 /* ======================================================================
   2457    FUNCTION
   2458    omx_vdec::SendCommandEvent
   2459 
   2460    DESCRIPTION
   2461    Send the event to decoder pipe.  This is needed to generate the callbacks
   2462    in decoder thread context.
   2463 
   2464    PARAMETERS
   2465    None.
   2466 
   2467    RETURN VALUE
   2468    true/false
   2469 
   2470    ========================================================================== */
   2471 bool omx_vdec::post_event(unsigned int p1,
   2472         unsigned int p2,
   2473         unsigned int id)
   2474 {
   2475     bool bRet      =                      false;
   2476 
   2477 
   2478     pthread_mutex_lock(&m_lock);
   2479 
   2480     if (id == m_fill_output_msg ||
   2481             id == OMX_COMPONENT_GENERATE_FBD) {
   2482         m_ftb_q.insert_entry(p1,p2,id);
   2483     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   2484             id == OMX_COMPONENT_GENERATE_EBD ||
   2485             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   2486         m_etb_q.insert_entry(p1,p2,id);
   2487     } else {
   2488         m_cmd_q.insert_entry(p1,p2,id);
   2489     }
   2490 
   2491     bRet = true;
   2492     DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
   2493     post_message(this, id);
   2494 
   2495     pthread_mutex_unlock(&m_lock);
   2496 
   2497     return bRet;
   2498 }
   2499 
   2500 OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   2501 {
   2502     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2503     if (!profileLevelType)
   2504         return OMX_ErrorBadParameter;
   2505 
   2506     if (profileLevelType->nPortIndex == 0) {
   2507         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   2508             if (profileLevelType->nProfileIndex == 0) {
   2509                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   2510                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2511 
   2512             } else if (profileLevelType->nProfileIndex == 1) {
   2513                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   2514                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2515             } else if (profileLevelType->nProfileIndex == 2) {
   2516                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   2517                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2518             } else {
   2519                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n",
   2520                         profileLevelType->nProfileIndex);
   2521                 eRet = OMX_ErrorNoMore;
   2522             }
   2523         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   2524             if (profileLevelType->nProfileIndex == 0) {
   2525                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   2526                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   2527             } else {
   2528                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
   2529                 eRet = OMX_ErrorNoMore;
   2530             }
   2531         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   2532             if (profileLevelType->nProfileIndex == 0) {
   2533                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2534                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   2535             } else if (profileLevelType->nProfileIndex == 1) {
   2536                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   2537                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   2538             } else {
   2539                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
   2540                 eRet = OMX_ErrorNoMore;
   2541             }
   2542         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   2543             eRet = OMX_ErrorNoMore;
   2544         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   2545             if (profileLevelType->nProfileIndex == 0) {
   2546                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   2547                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   2548             } else if (profileLevelType->nProfileIndex == 1) {
   2549                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   2550                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   2551             } else {
   2552                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %lu\n", profileLevelType->nProfileIndex);
   2553                 eRet = OMX_ErrorNoMore;
   2554             }
   2555         } else {
   2556             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s\n", drv_ctx.kind);
   2557             eRet = OMX_ErrorNoMore;
   2558         }
   2559     } else {
   2560         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %lu\n", profileLevelType->nPortIndex);
   2561         eRet = OMX_ErrorBadPortIndex;
   2562     }
   2563     return eRet;
   2564 }
   2565 
   2566 /* ======================================================================
   2567    FUNCTION
   2568    omx_vdec::GetParameter
   2569 
   2570    DESCRIPTION
   2571    OMX Get Parameter method implementation
   2572 
   2573    PARAMETERS
   2574    <TBD>.
   2575 
   2576    RETURN VALUE
   2577    Error None if successful.
   2578 
   2579    ========================================================================== */
   2580 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2581         OMX_IN OMX_INDEXTYPE paramIndex,
   2582         OMX_INOUT OMX_PTR     paramData)
   2583 {
   2584     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2585 
   2586     DEBUG_PRINT_LOW("get_parameter: \n");
   2587     if (m_state == OMX_StateInvalid) {
   2588         DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
   2589         return OMX_ErrorInvalidState;
   2590     }
   2591     if (paramData == NULL) {
   2592         DEBUG_PRINT_LOW("Get Param in Invalid paramData \n");
   2593         return OMX_ErrorBadParameter;
   2594     }
   2595     switch ((unsigned long)paramIndex) {
   2596         case OMX_IndexParamPortDefinition: {
   2597                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   2598                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2599                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
   2600                                eRet = update_portdef(portDefn);
   2601                                if (eRet == OMX_ErrorNone)
   2602                                    m_port_def = *portDefn;
   2603                                break;
   2604                            }
   2605         case OMX_IndexParamVideoInit: {
   2606                               OMX_PORT_PARAM_TYPE *portParamType =
   2607                                   (OMX_PORT_PARAM_TYPE *) paramData;
   2608                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
   2609 
   2610                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2611                               portParamType->nSize = sizeof(portParamType);
   2612                               portParamType->nPorts           = 2;
   2613                               portParamType->nStartPortNumber = 0;
   2614                               break;
   2615                           }
   2616         case OMX_IndexParamVideoPortFormat: {
   2617                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2618                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   2619                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
   2620 
   2621                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   2622                                 portFmt->nSize             = sizeof(portFmt);
   2623 
   2624                                 if (0 == portFmt->nPortIndex) {
   2625                                     if (0 == portFmt->nIndex) {
   2626                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   2627                                         portFmt->eCompressionFormat = eCompressionFormat;
   2628                                     } else {
   2629                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2630                                                 " NoMore compression formats\n");
   2631                                         eRet =  OMX_ErrorNoMore;
   2632                                     }
   2633                                 } else if (1 == portFmt->nPortIndex) {
   2634                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   2635 
   2636                                     if (0 == portFmt->nIndex)
   2637                                         portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
   2638                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2639                                     else if (1 == portFmt->nIndex)
   2640                                         portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
   2641                                     else {
   2642                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   2643                                                 " NoMore Color formats\n");
   2644                                         eRet =  OMX_ErrorNoMore;
   2645                                     }
   2646                                     DEBUG_PRINT_LOW("returning %d\n", portFmt->eColorFormat);
   2647                                 } else {
   2648                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
   2649                                             (int)portFmt->nPortIndex);
   2650                                     eRet = OMX_ErrorBadPortIndex;
   2651                                 }
   2652                                 break;
   2653                             }
   2654                             /*Component should support this port definition*/
   2655         case OMX_IndexParamAudioInit: {
   2656                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   2657                                   (OMX_PORT_PARAM_TYPE *) paramData;
   2658                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
   2659                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2660                               audioPortParamType->nSize = sizeof(audioPortParamType);
   2661                               audioPortParamType->nPorts           = 0;
   2662                               audioPortParamType->nStartPortNumber = 0;
   2663                               break;
   2664                           }
   2665                           /*Component should support this port definition*/
   2666         case OMX_IndexParamImageInit: {
   2667                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   2668                                   (OMX_PORT_PARAM_TYPE *) paramData;
   2669                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
   2670                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2671                               imagePortParamType->nSize = sizeof(imagePortParamType);
   2672                               imagePortParamType->nPorts           = 0;
   2673                               imagePortParamType->nStartPortNumber = 0;
   2674                               break;
   2675 
   2676                           }
   2677                           /*Component should support this port definition*/
   2678         case OMX_IndexParamOtherInit: {
   2679                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
   2680                                       paramIndex);
   2681                               eRet =OMX_ErrorUnsupportedIndex;
   2682                               break;
   2683                           }
   2684         case OMX_IndexParamStandardComponentRole: {
   2685                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   2686                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   2687                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   2688                                   comp_role->nSize = sizeof(*comp_role);
   2689 
   2690                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
   2691                                           paramIndex);
   2692                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   2693                                           OMX_MAX_STRINGNAME_SIZE);
   2694                                   break;
   2695                               }
   2696                               /* Added for parameter test */
   2697         case OMX_IndexParamPriorityMgmt: {
   2698 
   2699                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   2700                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   2701                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
   2702                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   2703                              priorityMgmType->nSize = sizeof(priorityMgmType);
   2704 
   2705                              break;
   2706                          }
   2707                          /* Added for parameter test */
   2708         case OMX_IndexParamCompBufferSupplier: {
   2709                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   2710                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   2711                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
   2712 
   2713                                    bufferSupplierType->nSize = sizeof(bufferSupplierType);
   2714                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   2715                                    if (0 == bufferSupplierType->nPortIndex)
   2716                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2717                                    else if (1 == bufferSupplierType->nPortIndex)
   2718                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   2719                                    else
   2720                                        eRet = OMX_ErrorBadPortIndex;
   2721 
   2722 
   2723                                    break;
   2724                                }
   2725         case OMX_IndexParamVideoAvc: {
   2726                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
   2727                                      paramIndex);
   2728                              break;
   2729                          }
   2730         case OMX_IndexParamVideoH263: {
   2731                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
   2732                                       paramIndex);
   2733                               break;
   2734                           }
   2735         case OMX_IndexParamVideoMpeg4: {
   2736                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
   2737                                        paramIndex);
   2738                                break;
   2739                            }
   2740         case OMX_IndexParamVideoMpeg2: {
   2741                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
   2742                                        paramIndex);
   2743                                break;
   2744                            }
   2745         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   2746                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
   2747                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   2748                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   2749                                         eRet = get_supported_profile_level_for_1080p(profileLevelType);
   2750                                         break;
   2751                                     }
   2752 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   2753         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   2754                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage\n");
   2755                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   2756                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   2757 
   2758                                             if (secure_mode) {
   2759                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   2760                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   2761                                             } else {
   2762                                                 nativeBuffersUsage->nUsage =
   2763                                                     (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
   2764                                                      GRALLOC_USAGE_PRIVATE_UNCACHED);
   2765                                             }
   2766                                         } else {
   2767                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!\n");
   2768                                             eRet = OMX_ErrorBadParameter;
   2769                                         }
   2770                                     }
   2771                                     break;
   2772 #endif
   2773 
   2774         default: {
   2775                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
   2776                  eRet =OMX_ErrorUnsupportedIndex;
   2777              }
   2778 
   2779     }
   2780 
   2781     DEBUG_PRINT_LOW("\n get_parameter returning WxH(%d x %d) SxSH(%d x %d)\n",
   2782             drv_ctx.video_resolution.frame_width,
   2783             drv_ctx.video_resolution.frame_height,
   2784             drv_ctx.video_resolution.stride,
   2785             drv_ctx.video_resolution.scan_lines);
   2786 
   2787     return eRet;
   2788 }
   2789 
   2790 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   2791 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   2792 {
   2793     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   2794     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2795     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   2796 
   2797     if ((params == NULL) ||
   2798             (params->nativeBuffer == NULL) ||
   2799             (params->nativeBuffer->handle == NULL) ||
   2800             !m_enable_android_native_buffers)
   2801         return OMX_ErrorBadParameter;
   2802     m_use_android_native_buffers = OMX_TRUE;
   2803     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   2804     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   2805     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   2806         OMX_U8 *buffer = NULL;
   2807         if (!secure_mode) {
   2808             buffer = (OMX_U8*)mmap(0, handle->size,
   2809                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   2810             if (buffer == MAP_FAILED) {
   2811                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   2812                 return OMX_ErrorInsufficientResources;
   2813             }
   2814         }
   2815         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   2816     } else {
   2817         eRet = OMX_ErrorBadParameter;
   2818     }
   2819     return eRet;
   2820 }
   2821 #endif
   2822 /* ======================================================================
   2823    FUNCTION
   2824    omx_vdec::Setparameter
   2825 
   2826    DESCRIPTION
   2827    OMX Set Parameter method implementation.
   2828 
   2829    PARAMETERS
   2830    <TBD>.
   2831 
   2832    RETURN VALUE
   2833    OMX Error None if successful.
   2834 
   2835    ========================================================================== */
   2836 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2837         OMX_IN OMX_INDEXTYPE paramIndex,
   2838         OMX_IN OMX_PTR        paramData)
   2839 {
   2840     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2841     int ret=0;
   2842     struct v4l2_format fmt;
   2843     if (m_state == OMX_StateInvalid) {
   2844         DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
   2845         return OMX_ErrorInvalidState;
   2846     }
   2847     if (paramData == NULL) {
   2848         DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
   2849         return OMX_ErrorBadParameter;
   2850     }
   2851     if ((m_state != OMX_StateLoaded) &&
   2852             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   2853             (m_out_bEnabled == OMX_TRUE) &&
   2854             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   2855             (m_inp_bEnabled == OMX_TRUE)) {
   2856         DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
   2857         return OMX_ErrorIncorrectStateOperation;
   2858     }
   2859     switch ((unsigned long)paramIndex) {
   2860         case OMX_IndexParamPortDefinition: {
   2861                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   2862                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2863                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   2864                                //been called.
   2865                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d\n",
   2866                                        (int)portDefn->format.video.nFrameHeight,
   2867                                        (int)portDefn->format.video.nFrameWidth);
   2868                                if (OMX_DirOutput == portDefn->eDir) {
   2869                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port\n");
   2870                                    m_display_id = portDefn->format.video.pNativeWindow;
   2871                                    unsigned int buffer_size;
   2872                                    if (!client_buffers.get_buffer_req(buffer_size)) {
   2873                                        DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
   2874                                        eRet = OMX_ErrorBadParameter;
   2875                                    } else {
   2876                                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
   2877                                                portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size ) {
   2878                                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
   2879                                            drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
   2880                                            drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
   2881                                            drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
   2882                                                drv_ctx.extradata_info.buffer_size;
   2883                                            eRet = set_buffer_req(&drv_ctx.op_buf);
   2884                                            if (eRet == OMX_ErrorNone)
   2885                                                m_port_def = *portDefn;
   2886                                        } else {
   2887                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
   2888                                                    drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
   2889                                                    portDefn->nBufferCountActual, portDefn->nBufferSize);
   2890                                            eRet = OMX_ErrorBadParameter;
   2891                                        }
   2892                                    }
   2893                                } else if (OMX_DirInput == portDefn->eDir) {
   2894                                    bool port_format_changed = false;
   2895                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   2896                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   2897                                        // Frame rate only should be set if this is a "known value" or to
   2898                                        // activate ts prediction logic (arbitrary mode only) sending input
   2899                                        // timestamps with max value (LLONG_MAX).
   2900                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %lu",
   2901                                                portDefn->format.video.xFramerate >> 16);
   2902                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   2903                                                drv_ctx.frame_rate.fps_denominator);
   2904                                        if (!drv_ctx.frame_rate.fps_numerator) {
   2905                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   2906                                            drv_ctx.frame_rate.fps_numerator = 30;
   2907                                        }
   2908                                        if (drv_ctx.frame_rate.fps_denominator)
   2909                                            drv_ctx.frame_rate.fps_numerator = (int)
   2910                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   2911                                        drv_ctx.frame_rate.fps_denominator = 1;
   2912                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   2913                                            drv_ctx.frame_rate.fps_numerator;
   2914                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%lu) fps(%.2f)",
   2915                                                frm_int, drv_ctx.frame_rate.fps_numerator /
   2916                                                (float)drv_ctx.frame_rate.fps_denominator);
   2917                                    }
   2918                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port\n");
   2919                                    if (drv_ctx.video_resolution.frame_height !=
   2920                                            portDefn->format.video.nFrameHeight ||
   2921                                            drv_ctx.video_resolution.frame_width  !=
   2922                                            portDefn->format.video.nFrameWidth) {
   2923                                        DEBUG_PRINT_LOW("\n SetParam IP: WxH(%lu x %lu)\n",
   2924                                                portDefn->format.video.nFrameWidth,
   2925                                                portDefn->format.video.nFrameHeight);
   2926                                        port_format_changed = true;
   2927                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   2928                                                portDefn->format.video.nFrameWidth != 0x0) {
   2929                                            update_resolution(portDefn->format.video.nFrameWidth,
   2930                                                    portDefn->format.video.nFrameHeight,
   2931                                                    portDefn->format.video.nFrameWidth,
   2932                                                    portDefn->format.video.nFrameHeight);
   2933                                            eRet = is_video_session_supported();
   2934                                            if (eRet)
   2935                                                break;
   2936                                            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2937                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2938                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2939                                            fmt.fmt.pix_mp.pixelformat = output_capability;
   2940                                            DEBUG_PRINT_LOW("\n fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d \n",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   2941                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2942                                            if (ret) {
   2943                                                DEBUG_PRINT_ERROR("\n Set Resolution failed");
   2944                                                eRet = OMX_ErrorUnsupportedSetting;
   2945                                            } else
   2946                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   2947                                        }
   2948                                    }
   2949                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   2950                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   2951                                        port_format_changed = true;
   2952                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   2953                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   2954                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   2955                                            (~(buffer_prop->alignment - 1));
   2956                                        eRet = set_buffer_req(buffer_prop);
   2957                                    }
   2958                                    if (false == port_format_changed) {
   2959                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%lu: %lu)\n",
   2960                                                drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
   2961                                                portDefn->nBufferCountActual, portDefn->nBufferSize);
   2962                                        eRet = OMX_ErrorBadParameter;
   2963                                    }
   2964                                } else if (portDefn->eDir ==  OMX_DirMax) {
   2965                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   2966                                            (int)portDefn->nPortIndex);
   2967                                    eRet = OMX_ErrorBadPortIndex;
   2968                                }
   2969                            }
   2970                            break;
   2971         case OMX_IndexParamVideoPortFormat: {
   2972                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2973                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   2974                                 int ret=0;
   2975                                 struct v4l2_format fmt;
   2976                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat %d\n",
   2977                                         portFmt->eColorFormat);
   2978 
   2979                                 if (1 == portFmt->nPortIndex) {
   2980                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2981                                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2982                                     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2983                                     fmt.fmt.pix_mp.pixelformat = capture_capability;
   2984                                     enum vdec_output_fromat op_format;
   2985                                     if ((portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   2986                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) ||
   2987                                             (portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar))
   2988                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   2989                                     else if (portFmt->eColorFormat ==
   2990                                             (OMX_COLOR_FORMATTYPE)
   2991                                             QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka)
   2992                                         op_format = VDEC_YUV_FORMAT_TILE_4x2;
   2993                                     else
   2994                                         eRet = OMX_ErrorBadParameter;
   2995 
   2996                                     if (eRet == OMX_ErrorNone) {
   2997                                         drv_ctx.output_format = op_format;
   2998                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2999                                         if (ret) {
   3000                                             DEBUG_PRINT_ERROR("\n Set output format failed");
   3001                                             eRet = OMX_ErrorUnsupportedSetting;
   3002                                             /*TODO: How to handle this case */
   3003                                         } else {
   3004                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   3005                                         }
   3006                                     }
   3007                                     if (eRet == OMX_ErrorNone) {
   3008                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   3009                                             DEBUG_PRINT_ERROR("\n Set color format failed");
   3010                                             eRet = OMX_ErrorBadParameter;
   3011                                         }
   3012                                     }
   3013                                 }
   3014                             }
   3015                             break;
   3016 
   3017         case OMX_QcomIndexPortDefn: {
   3018                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   3019                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   3020                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %lu\n",
   3021                                     portFmt->nFramePackingFormat);
   3022 
   3023                             /* Input port */
   3024                             if (portFmt->nPortIndex == 0) {
   3025                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   3026                                     if (secure_mode) {
   3027                                         arbitrary_bytes = false;
   3028                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
   3029                                         eRet = OMX_ErrorUnsupportedSetting;
   3030                                     } else {
   3031                                         arbitrary_bytes = true;
   3032                                     }
   3033                                 } else if (portFmt->nFramePackingFormat ==
   3034                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   3035                                     arbitrary_bytes = false;
   3036                                 } else {
   3037                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %lu\n",
   3038                                             portFmt->nFramePackingFormat);
   3039                                     eRet = OMX_ErrorUnsupportedSetting;
   3040                                 }
   3041                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3042                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port\n");
   3043                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   3044                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   3045                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   3046                                     m_out_mem_region_smi = OMX_TRUE;
   3047                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   3048                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set\n");
   3049                                         m_use_output_pmem = OMX_TRUE;
   3050                                     }
   3051                                 }
   3052                             }
   3053                         }
   3054                         break;
   3055 
   3056         case OMX_IndexParamStandardComponentRole: {
   3057                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3058                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3059                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s\n",
   3060                                           comp_role->cRole);
   3061 
   3062                                   if ((m_state == OMX_StateLoaded)&&
   3063                                           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   3064                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   3065                                   } else {
   3066                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   3067                                       return OMX_ErrorIncorrectStateOperation;
   3068                                   }
   3069 
   3070                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3071                                       if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3072                                           strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3073                                       } else {
   3074                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3075                                           eRet =OMX_ErrorUnsupportedSetting;
   3076                                       }
   3077                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3078                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3079                                           strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3080                                       } else {
   3081                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3082                                           eRet = OMX_ErrorUnsupportedSetting;
   3083                                       }
   3084                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3085                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3086                                           strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3087                                       } else {
   3088                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3089                                           eRet =OMX_ErrorUnsupportedSetting;
   3090                                       }
   3091                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3092                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3093                                           strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   3094                                       } else {
   3095                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3096                                           eRet = OMX_ErrorUnsupportedSetting;
   3097                                       }
   3098                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   3099                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
   3100                                         ) {
   3101                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
   3102                                           strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   3103                                       } else {
   3104                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3105                                           eRet =OMX_ErrorUnsupportedSetting;
   3106                                       }
   3107                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   3108                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   3109                                         ) {
   3110                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
   3111                                           strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   3112                                       } else {
   3113                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3114                                           eRet =OMX_ErrorUnsupportedSetting;
   3115                                       }
   3116                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   3117                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3118                                               (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
   3119                                           strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   3120                                       } else {
   3121                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
   3122                                           eRet = OMX_ErrorUnsupportedSetting;
   3123                                       }
   3124                                   } else {
   3125                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
   3126                                       eRet = OMX_ErrorInvalidComponentName;
   3127                                   }
   3128                                   break;
   3129                               }
   3130 
   3131         case OMX_IndexParamPriorityMgmt: {
   3132                              if (m_state != OMX_StateLoaded) {
   3133                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
   3134                                  return OMX_ErrorIncorrectStateOperation;
   3135                              }
   3136                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   3137                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %lu\n",
   3138                                      priorityMgmtype->nGroupID);
   3139 
   3140                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %lu\n",
   3141                                      priorityMgmtype->nGroupPriority);
   3142 
   3143                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   3144                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   3145 
   3146                              break;
   3147                          }
   3148 
   3149         case OMX_IndexParamCompBufferSupplier: {
   3150                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3151                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
   3152                                            bufferSupplierType->eBufferSupplier);
   3153                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   3154                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   3155 
   3156                                    else
   3157 
   3158                                        eRet = OMX_ErrorBadPortIndex;
   3159 
   3160                                    break;
   3161 
   3162                                }
   3163         case OMX_IndexParamVideoAvc: {
   3164                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
   3165                                      paramIndex);
   3166                              break;
   3167                          }
   3168         case OMX_IndexParamVideoH263: {
   3169                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
   3170                                       paramIndex);
   3171                               break;
   3172                           }
   3173         case OMX_IndexParamVideoMpeg4: {
   3174                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
   3175                                        paramIndex);
   3176                                break;
   3177                            }
   3178         case OMX_IndexParamVideoMpeg2: {
   3179                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
   3180                                        paramIndex);
   3181                                break;
   3182                            }
   3183         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   3184                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   3185                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   3186                                      struct v4l2_control control;
   3187                                      int pic_order,rc=0;
   3188                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
   3189                                              pictureOrder->eOutputPictureOrder);
   3190                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   3191                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   3192                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   3193                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   3194                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   3195                                      } else
   3196                                          eRet = OMX_ErrorBadParameter;
   3197                                      if (eRet == OMX_ErrorNone) {
   3198                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   3199                                          control.value = pic_order;
   3200                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3201                                          if (rc) {
   3202                                              DEBUG_PRINT_ERROR("\n Set picture order failed");
   3203                                              eRet = OMX_ErrorUnsupportedSetting;
   3204                                          }
   3205                                      }
   3206                                      break;
   3207                                  }
   3208         case OMX_QcomIndexParamConcealMBMapExtraData:
   3209                                  if (!secure_mode)
   3210                                      eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   3211                                              ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3212                                  else {
   3213                                      DEBUG_PRINT_ERROR("\n secure mode setting not supported");
   3214                                      eRet = OMX_ErrorUnsupportedSetting;
   3215                                  }
   3216                                  break;
   3217         case OMX_QcomIndexParamFrameInfoExtraData: {
   3218                                    if (!secure_mode)
   3219                                        eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   3220                                                ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3221                                    else {
   3222                                        DEBUG_PRINT_ERROR("\n secure mode setting not supported");
   3223                                        eRet = OMX_ErrorUnsupportedSetting;
   3224                                    }
   3225                                    break;
   3226                                }
   3227         case OMX_QcomIndexParamInterlaceExtraData:
   3228                                if (!secure_mode)
   3229                                    eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   3230                                            ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3231                                else {
   3232                                    DEBUG_PRINT_ERROR("\n secure mode setting not supported");
   3233                                    eRet = OMX_ErrorUnsupportedSetting;
   3234                                }
   3235                                break;
   3236         case OMX_QcomIndexParamH264TimeInfo:
   3237                                if (!secure_mode)
   3238                                    eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   3239                                            ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3240                                else {
   3241                                    DEBUG_PRINT_ERROR("\n secure mode setting not supported");
   3242                                    eRet = OMX_ErrorUnsupportedSetting;
   3243                                }
   3244                                break;
   3245         case OMX_QcomIndexParamVideoDivx: {
   3246                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   3247                           }
   3248                           break;
   3249         case OMX_QcomIndexPlatformPvt: {
   3250                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port\n");
   3251                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   3252                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   3253                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   3254                                    eRet = OMX_ErrorUnsupportedSetting;
   3255                                } else {
   3256                                    m_out_pvt_entry_pmem = OMX_TRUE;
   3257                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   3258                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set\n");
   3259                                        m_use_output_pmem = OMX_TRUE;
   3260                                    }
   3261                                }
   3262 
   3263                            }
   3264                            break;
   3265         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   3266                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   3267                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   3268                                        struct v4l2_control control;
   3269                                        int rc;
   3270                                        drv_ctx.idr_only_decoding = 1;
   3271                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   3272                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   3273                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3274                                        if (rc) {
   3275                                            DEBUG_PRINT_ERROR("\n Set picture order failed");
   3276                                            eRet = OMX_ErrorUnsupportedSetting;
   3277                                        } else {
   3278                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   3279                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   3280                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3281                                            if (rc) {
   3282                                                DEBUG_PRINT_ERROR("\n Sync frame setting failed");
   3283                                                eRet = OMX_ErrorUnsupportedSetting;
   3284                                            }
   3285                                            /*Setting sync frame decoding on driver might change buffer
   3286                                             * requirements so update them here*/
   3287                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   3288                                                DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer i/p requirements");
   3289                                                eRet = OMX_ErrorUnsupportedSetting;
   3290                                            }
   3291                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   3292                                                DEBUG_PRINT_ERROR("\n Sync frame setting failed: falied to get buffer o/p requirements");
   3293                                                eRet = OMX_ErrorUnsupportedSetting;
   3294                                            }
   3295                                        }
   3296                                    }
   3297                                    break;
   3298 
   3299         case OMX_QcomIndexParamIndexExtraDataType: {
   3300                                    if (!secure_mode) {
   3301                                        QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   3302                                        if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   3303                                                (extradataIndexType->bEnabled == OMX_TRUE) &&
   3304                                                (extradataIndexType->nPortIndex == 1)) {
   3305                                            DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming\n");
   3306                                            eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   3307 
   3308                                        }
   3309                                    }
   3310                                }
   3311                                break;
   3312         case OMX_QcomIndexParamEnableSmoothStreaming: {
   3313 #ifndef SMOOTH_STREAMING_DISABLED
   3314                                       struct v4l2_control control;
   3315                                       struct v4l2_format fmt;
   3316                                       control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   3317                                       control.value = 1;
   3318                                       int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3319                                       if (rc < 0) {
   3320                                           DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   3321                                           eRet = OMX_ErrorHardware;
   3322                                       }
   3323 #else
   3324                                       eRet = OMX_ErrorUnsupportedSetting;
   3325 #endif
   3326                                   }
   3327                                   break;
   3328 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3329                                   /* Need to allow following two set_parameters even in Idle
   3330                                    * state. This is ANDROID architecture which is not in sync
   3331                                    * with openmax standard. */
   3332         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   3333                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   3334                                            if (enableNativeBuffers) {
   3335                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   3336                                            }
   3337                                        }
   3338                                        break;
   3339         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   3340                                        eRet = use_android_native_buffer(hComp, paramData);
   3341                                    }
   3342                                    break;
   3343 #endif
   3344         case OMX_QcomIndexParamEnableTimeStampReorder: {
   3345                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   3346                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   3347                                            if (reorder->bEnable == OMX_TRUE) {
   3348                                                frm_int =0;
   3349                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   3350                                            } else
   3351                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   3352                                        } else {
   3353                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   3354                                            if (reorder->bEnable == OMX_TRUE) {
   3355                                                eRet = OMX_ErrorUnsupportedSetting;
   3356                                            }
   3357                                        }
   3358                                    }
   3359                                    break;
   3360         case OMX_IndexParamVideoProfileLevelCurrent: {
   3361                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   3362                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3363                                      if (pParam) {
   3364                                          m_profile_lvl.eProfile = pParam->eProfile;
   3365                                          m_profile_lvl.eLevel = pParam->eLevel;
   3366                                      }
   3367                                      break;
   3368 
   3369                                  }
   3370         case OMX_QcomIndexParamVideoMetaBufferMode:
   3371         {
   3372             StoreMetaDataInBuffersParams *metabuffer =
   3373                 (StoreMetaDataInBuffersParams *)paramData;
   3374             if (!metabuffer) {
   3375                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   3376                 eRet = OMX_ErrorBadParameter;
   3377                 break;
   3378             }
   3379             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX &&
   3380                 metabuffer->bStoreMetaData == true) {
   3381                     //set property dynamic buffer mode to driver.
   3382                     struct v4l2_control control;
   3383                     struct v4l2_format fmt;
   3384                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   3385                     control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   3386                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3387                     if (rc) {
   3388                         DEBUG_PRINT_ERROR("Failed to set dynamic buffer mode on driver.");
   3389                         eRet = OMX_ErrorUnsupportedSetting;
   3390                     } else {
   3391                         dynamic_buf_mode = true;
   3392                     }
   3393                 } else {
   3394                     DEBUG_PRINT_ERROR("Dynamic buffer mode not supported for port: %d\n",
   3395                              metabuffer->nPortIndex);
   3396                     eRet = OMX_ErrorUnsupportedSetting;
   3397                 }
   3398                 break;
   3399         }
   3400         default: {
   3401                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
   3402                  eRet = OMX_ErrorUnsupportedIndex;
   3403              }
   3404     }
   3405     return eRet;
   3406 }
   3407 
   3408 /* ======================================================================
   3409    FUNCTION
   3410    omx_vdec::GetConfig
   3411 
   3412    DESCRIPTION
   3413    OMX Get Config Method implementation.
   3414 
   3415    PARAMETERS
   3416    <TBD>.
   3417 
   3418    RETURN VALUE
   3419    OMX Error None if successful.
   3420 
   3421    ========================================================================== */
   3422 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   3423         OMX_IN OMX_INDEXTYPE configIndex,
   3424         OMX_INOUT OMX_PTR     configData)
   3425 {
   3426     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3427 
   3428     if (m_state == OMX_StateInvalid) {
   3429         DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   3430         return OMX_ErrorInvalidState;
   3431     }
   3432 
   3433     switch ((unsigned long)configIndex) {
   3434         case OMX_QcomIndexConfigInterlaced: {
   3435                                 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   3436                                     (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   3437                                 if (configFmt->nPortIndex == 1) {
   3438                                     if (configFmt->nIndex == 0) {
   3439                                         configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   3440                                     } else if (configFmt->nIndex == 1) {
   3441                                         configFmt->eInterlaceType =
   3442                                             OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   3443                                     } else if (configFmt->nIndex == 2) {
   3444                                         configFmt->eInterlaceType =
   3445                                             OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   3446                                     } else {
   3447                                         DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   3448                                                 " NoMore Interlaced formats\n");
   3449                                         eRet = OMX_ErrorNoMore;
   3450                                     }
   3451 
   3452                                 } else {
   3453                                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
   3454                                             (int)configFmt->nPortIndex);
   3455                                     eRet = OMX_ErrorBadPortIndex;
   3456                                 }
   3457                                 break;
   3458                             }
   3459         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
   3460                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   3461                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   3462                                      decoderinstances->nNumOfInstances = 16;
   3463                                      /*TODO: How to handle this case */
   3464                                      break;
   3465                                  }
   3466         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
   3467                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   3468                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
   3469                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
   3470                                               h264_parser->get_frame_pack_data(configFmt);
   3471                                           } else {
   3472                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
   3473                                           }
   3474                                           break;
   3475                                       }
   3476         case OMX_IndexConfigCommonOutputCrop: {
   3477                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   3478                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   3479                                   break;
   3480                               }
   3481         default: {
   3482                  DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
   3483                  eRet = OMX_ErrorBadParameter;
   3484              }
   3485 
   3486     }
   3487 
   3488     return eRet;
   3489 }
   3490 
   3491 /* ======================================================================
   3492    FUNCTION
   3493    omx_vdec::SetConfig
   3494 
   3495    DESCRIPTION
   3496    OMX Set Config method implementation
   3497 
   3498    PARAMETERS
   3499    <TBD>.
   3500 
   3501    RETURN VALUE
   3502    OMX Error None if successful.
   3503    ========================================================================== */
   3504 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   3505         OMX_IN OMX_INDEXTYPE configIndex,
   3506         OMX_IN OMX_PTR        configData)
   3507 {
   3508     if (m_state == OMX_StateInvalid) {
   3509         DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
   3510         return OMX_ErrorInvalidState;
   3511     }
   3512 
   3513     OMX_ERRORTYPE ret = OMX_ErrorNone;
   3514     OMX_VIDEO_CONFIG_NALSIZE *pNal;
   3515 
   3516     DEBUG_PRINT_LOW("\n Set Config Called");
   3517 
   3518     if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
   3519         OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
   3520         DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData called");
   3521         if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
   3522             DEBUG_PRINT_LOW("\n Index OMX_IndexVendorVideoExtraData AVC");
   3523             OMX_U32 extra_size;
   3524             // Parsing done here for the AVC atom is definitely not generic
   3525             // Currently this piece of code is working, but certainly
   3526             // not tested with all .mp4 files.
   3527             // Incase of failure, we might need to revisit this
   3528             // for a generic piece of code.
   3529 
   3530             // Retrieve size of NAL length field
   3531             // byte #4 contains the size of NAL lenght field
   3532             nal_length = (config->pData[4] & 0x03) + 1;
   3533 
   3534             extra_size = 0;
   3535             if (nal_length > 2) {
   3536                 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
   3537                 extra_size = (nal_length - 2) * 2;
   3538             }
   3539 
   3540             // SPS starts from byte #6
   3541             OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
   3542             OMX_U8 *pDestBuf;
   3543             m_vendor_config.nPortIndex = config->nPortIndex;
   3544 
   3545             // minus 6 --> SPS starts from byte #6
   3546             // minus 1 --> picture param set byte to be ignored from avcatom
   3547             m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
   3548             m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
   3549             OMX_U32 len;
   3550             OMX_U8 index = 0;
   3551             // case where SPS+PPS is sent as part of set_config
   3552             pDestBuf = m_vendor_config.pData;
   3553 
   3554             DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%lu] len[%lu] data[%p]\n",
   3555                     m_vendor_config.nPortIndex,
   3556                     m_vendor_config.nDataSize,
   3557                     m_vendor_config.pData);
   3558             while (index < 2) {
   3559                 uint8 *psize;
   3560                 len = *pSrcBuf;
   3561                 len = len << 8;
   3562                 len |= *(pSrcBuf + 1);
   3563                 psize = (uint8 *) & len;
   3564                 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
   3565                 for (unsigned int i = 0; i < nal_length; i++) {
   3566                     pDestBuf[i] = psize[nal_length - 1 - i];
   3567                 }
   3568                 //memcpy(pDestBuf,pSrcBuf,(len+2));
   3569                 pDestBuf += len + nal_length;
   3570                 pSrcBuf += len + 2;
   3571                 index++;
   3572                 pSrcBuf++;   // skip picture param set
   3573                 len = 0;
   3574             }
   3575         } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
   3576                 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
   3577             m_vendor_config.nPortIndex = config->nPortIndex;
   3578             m_vendor_config.nDataSize = config->nDataSize;
   3579             m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
   3580             memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
   3581         } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
   3582             if (m_vendor_config.pData) {
   3583                 free(m_vendor_config.pData);
   3584                 m_vendor_config.pData = NULL;
   3585                 m_vendor_config.nDataSize = 0;
   3586             }
   3587 
   3588             if (((*((OMX_U32 *) config->pData)) &
   3589                         VC1_SP_MP_START_CODE_MASK) ==
   3590                     VC1_SP_MP_START_CODE) {
   3591                 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
   3592                 m_vendor_config.nPortIndex = config->nPortIndex;
   3593                 m_vendor_config.nDataSize = config->nDataSize;
   3594                 m_vendor_config.pData =
   3595                     (OMX_U8 *) malloc(config->nDataSize);
   3596                 memcpy(m_vendor_config.pData, config->pData,
   3597                         config->nDataSize);
   3598                 m_vc1_profile = VC1_SP_MP_RCV;
   3599             } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
   3600                 DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
   3601                 m_vendor_config.nPortIndex = config->nPortIndex;
   3602                 m_vendor_config.nDataSize = config->nDataSize;
   3603                 m_vendor_config.pData =
   3604                     (OMX_U8 *) malloc((config->nDataSize));
   3605                 memcpy(m_vendor_config.pData, config->pData,
   3606                         config->nDataSize);
   3607                 m_vc1_profile = VC1_AP;
   3608             } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
   3609                 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
   3610                 m_vendor_config.nPortIndex = config->nPortIndex;
   3611                 m_vendor_config.nDataSize  = config->nDataSize;
   3612                 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
   3613                 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
   3614                 m_vc1_profile = VC1_SP_MP_RCV;
   3615             } else {
   3616                 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
   3617             }
   3618         }
   3619         return ret;
   3620     } else if (configIndex == OMX_IndexConfigVideoNalSize) {
   3621         struct v4l2_control temp;
   3622         temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
   3623 
   3624         pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   3625         switch (pNal->nNaluBytes) {
   3626             case 0:
   3627                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
   3628                 break;
   3629             case 2:
   3630                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
   3631                 break;
   3632             case 4:
   3633                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
   3634                 break;
   3635             default:
   3636                 return OMX_ErrorUnsupportedSetting;
   3637         }
   3638 
   3639         if (!arbitrary_bytes) {
   3640             /* In arbitrary bytes mode, the assembler strips out nal size and replaces
   3641              * with start code, so only need to notify driver in frame by frame mode */
   3642             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
   3643                 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
   3644                 return OMX_ErrorHardware;
   3645             }
   3646         }
   3647 
   3648         nal_length = pNal->nNaluBytes;
   3649         m_frame_parser.init_nal_length(nal_length);
   3650 
   3651         DEBUG_PRINT_LOW("\n OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
   3652         return ret;
   3653     } else if (configIndex == OMX_IndexVendorVideoFrameRate) {
   3654         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   3655         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %d", config->nFps);
   3656 
   3657         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   3658             if (config->bEnabled) {
   3659                 if ((config->nFps >> 16) > 0) {
   3660                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %d",
   3661                             config->nFps >> 16);
   3662                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   3663                             drv_ctx.frame_rate.fps_denominator);
   3664 
   3665                     if (!drv_ctx.frame_rate.fps_numerator) {
   3666                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   3667                         drv_ctx.frame_rate.fps_numerator = 30;
   3668                     }
   3669 
   3670                     if (drv_ctx.frame_rate.fps_denominator) {
   3671                         drv_ctx.frame_rate.fps_numerator = (int)
   3672                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   3673                     }
   3674 
   3675                     drv_ctx.frame_rate.fps_denominator = 1;
   3676                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   3677                         drv_ctx.frame_rate.fps_numerator;
   3678 
   3679                     struct v4l2_outputparm oparm;
   3680                     /*XXX: we're providing timing info as seconds per frame rather than frames
   3681                      * per second.*/
   3682                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   3683                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   3684 
   3685                     struct v4l2_streamparm sparm;
   3686                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3687                     sparm.parm.output = oparm;
   3688                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   3689                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   3690                                 performance might be affected");
   3691                         ret = OMX_ErrorHardware;
   3692                     }
   3693                     client_set_fps = true;
   3694                 } else {
   3695                     DEBUG_PRINT_ERROR("Frame rate not supported.");
   3696                     ret = OMX_ErrorUnsupportedSetting;
   3697                 }
   3698             } else {
   3699                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   3700                 client_set_fps = false;
   3701             }
   3702         } else {
   3703             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   3704                     (int)config->nPortIndex);
   3705             ret = OMX_ErrorBadPortIndex;
   3706         }
   3707 
   3708         return ret;
   3709     }
   3710 
   3711     return OMX_ErrorNotImplemented;
   3712 }
   3713 
   3714 /* ======================================================================
   3715    FUNCTION
   3716    omx_vdec::GetExtensionIndex
   3717 
   3718    DESCRIPTION
   3719    OMX GetExtensionIndex method implementaion.  <TBD>
   3720 
   3721    PARAMETERS
   3722    <TBD>.
   3723 
   3724    RETURN VALUE
   3725    OMX Error None if everything successful.
   3726 
   3727    ========================================================================== */
   3728 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   3729         OMX_IN OMX_STRING      paramName,
   3730         OMX_OUT OMX_INDEXTYPE* indexType)
   3731 {
   3732     if (m_state == OMX_StateInvalid) {
   3733         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
   3734         return OMX_ErrorInvalidState;
   3735     } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
   3736         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
   3737     } else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
   3738         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
   3739     }
   3740 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3741     else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
   3742         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   3743     } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
   3744         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   3745     } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
   3746         DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
   3747         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   3748     } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
   3749         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   3750     }
   3751 #endif
   3752     else if (!strncmp(paramName, "OMX.google.android.index.storeMetaDataInBuffers", sizeof("OMX.google.android.index.storeMetaDataInBuffers") - 1)) {
   3753         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   3754     }
   3755     else {
   3756         DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
   3757         return OMX_ErrorNotImplemented;
   3758     }
   3759     return OMX_ErrorNone;
   3760 }
   3761 
   3762 /* ======================================================================
   3763    FUNCTION
   3764    omx_vdec::GetState
   3765 
   3766    DESCRIPTION
   3767    Returns the state information back to the caller.<TBD>
   3768 
   3769    PARAMETERS
   3770    <TBD>.
   3771 
   3772    RETURN VALUE
   3773    Error None if everything is successful.
   3774    ========================================================================== */
   3775 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   3776         OMX_OUT OMX_STATETYPE* state)
   3777 {
   3778     *state = m_state;
   3779     DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
   3780     return OMX_ErrorNone;
   3781 }
   3782 
   3783 /* ======================================================================
   3784    FUNCTION
   3785    omx_vdec::ComponentTunnelRequest
   3786 
   3787    DESCRIPTION
   3788    OMX Component Tunnel Request method implementation. <TBD>
   3789 
   3790    PARAMETERS
   3791    None.
   3792 
   3793    RETURN VALUE
   3794    OMX Error None if everything successful.
   3795 
   3796    ========================================================================== */
   3797 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
   3798         OMX_IN OMX_U32                        port,
   3799         OMX_IN OMX_HANDLETYPE        peerComponent,
   3800         OMX_IN OMX_U32                    peerPort,
   3801         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   3802 {
   3803     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
   3804     return OMX_ErrorNotImplemented;
   3805 }
   3806 
   3807 /* ======================================================================
   3808    FUNCTION
   3809    omx_vdec::UseOutputBuffer
   3810 
   3811    DESCRIPTION
   3812    Helper function for Use buffer in the input pin
   3813 
   3814    PARAMETERS
   3815    None.
   3816 
   3817    RETURN VALUE
   3818    true/false
   3819 
   3820    ========================================================================== */
   3821 OMX_ERRORTYPE omx_vdec::allocate_extradata()
   3822 {
   3823 #ifdef USE_ION
   3824     auto_lock extradata_lock(&e_lock);
   3825     if (drv_ctx.extradata_info.buffer_size) {
   3826         if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
   3827             munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   3828             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   3829             free_ion_memory(&drv_ctx.extradata_info.ion);
   3830             memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
   3831         }
   3832         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
   3833         drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
   3834                 drv_ctx.extradata_info.size, 4096,
   3835                 &drv_ctx.extradata_info.ion.ion_alloc_data,
   3836                 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
   3837         if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
   3838             DEBUG_PRINT_ERROR("Failed to alloc extradata memory\n");
   3839             return OMX_ErrorInsufficientResources;
   3840         }
   3841         drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
   3842                 drv_ctx.extradata_info.size,
   3843                 PROT_READ|PROT_WRITE, MAP_SHARED,
   3844                 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
   3845         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
   3846             DEBUG_PRINT_ERROR("Failed to map extradata memory\n");
   3847             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   3848             free_ion_memory(&drv_ctx.extradata_info.ion);
   3849             return OMX_ErrorInsufficientResources;
   3850         }
   3851     }
   3852 #endif
   3853     return OMX_ErrorNone;
   3854 }
   3855 
   3856 void omx_vdec::free_extradata()
   3857 {
   3858 #ifdef USE_ION
   3859     auto_lock extradata_lock(&e_lock);
   3860     if (drv_ctx.extradata_info.uaddr) {
   3861         munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   3862         close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   3863         free_ion_memory(&drv_ctx.extradata_info.ion);
   3864     }
   3865     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
   3866 #endif
   3867 }
   3868 
   3869 OMX_ERRORTYPE  omx_vdec::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 vdec_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     if (!m_out_mem_ptr) {
   3889         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
   3890         eRet = allocate_output_headers();
   3891         if (eRet == OMX_ErrorNone)
   3892             eRet = allocate_extradata();
   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                 break;
   3899             }
   3900         }
   3901     }
   3902 
   3903     if (i >= drv_ctx.op_buf.actualcount) {
   3904         DEBUG_PRINT_ERROR("Already using %d o/p buffers\n", drv_ctx.op_buf.actualcount);
   3905         eRet = OMX_ErrorInsufficientResources;
   3906     }
   3907 
   3908     if (dynamic_buf_mode) {
   3909         *bufferHdr = (m_out_mem_ptr + i );
   3910         (*bufferHdr)->pBuffer = NULL;
   3911         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   3912             enum v4l2_buf_type buf_type;
   3913             int rr = 0;
   3914             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3915             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   3916                 DEBUG_PRINT_ERROR(" STREAMON FAILED : %d",rr);
   3917                 return OMX_ErrorInsufficientResources;
   3918             } else {
   3919                 streaming[CAPTURE_PORT] = true;
   3920                 DEBUG_PRINT_HIGH("\n STREAMON Successful \n ");
   3921             }
   3922         }
   3923         BITMASK_SET(&m_out_bm_count,i);
   3924         (*bufferHdr)->pAppPrivate = appData;
   3925         (*bufferHdr)->pBuffer = buffer;
   3926         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   3927         return eRet;
   3928     }
   3929 
   3930     if (eRet == OMX_ErrorNone) {
   3931 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   3932         if (m_enable_android_native_buffers) {
   3933             if (m_use_android_native_buffers) {
   3934                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   3935                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   3936                 handle = (private_handle_t *)nBuf->handle;
   3937                 privateAppData = params->pAppPrivate;
   3938             } else {
   3939                 handle = (private_handle_t *)buff;
   3940                 privateAppData = appData;
   3941             }
   3942 
   3943             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   3944                 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   3945                         " expected %u, got %lu",
   3946                         drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
   3947                 return OMX_ErrorBadParameter;
   3948             }
   3949 
   3950             if (!m_use_android_native_buffers) {
   3951                 if (!secure_mode) {
   3952                     buff =  (OMX_U8*)mmap(0, handle->size,
   3953                             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   3954                     if (buff == MAP_FAILED) {
   3955                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   3956                         return OMX_ErrorInsufficientResources;
   3957                     }
   3958                 }
   3959             }
   3960 #if defined(_ANDROID_ICS_)
   3961             native_buffer[i].nativehandle = handle;
   3962             native_buffer[i].privatehandle = handle;
   3963 #endif
   3964             if (!handle) {
   3965                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   3966                 return OMX_ErrorBadParameter;
   3967             }
   3968             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   3969             drv_ctx.ptr_outputbuffer[i].offset = 0;
   3970             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   3971             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   3972             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   3973         } else
   3974 #endif
   3975 
   3976             if (!ouput_egl_buffers && !m_use_output_pmem) {
   3977 #ifdef USE_ION
   3978                 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   3979                         drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   3980                         &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   3981                         &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
   3982                 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   3983                     DEBUG_PRINT_ERROR("ION device fd is bad %d\n", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   3984                     return OMX_ErrorInsufficientResources;
   3985                 }
   3986                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   3987                                       drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   3988 #else
   3989                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   3990                                       open (MEM_DEVICE,O_RDWR);
   3991 
   3992                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   3993                     DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   3994                     return OMX_ErrorInsufficientResources;
   3995                 }
   3996 
   3997                 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
   3998                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
   3999                     drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   4000                                           open (MEM_DEVICE,O_RDWR);
   4001                     if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   4002                         DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d\n", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4003                         return OMX_ErrorInsufficientResources;
   4004                     }
   4005                 }
   4006 
   4007                 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   4008                             drv_ctx.op_buf.buffer_size,
   4009                             drv_ctx.op_buf.alignment)) {
   4010                     DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   4011                     close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4012                     return OMX_ErrorInsufficientResources;
   4013                 }
   4014 #endif
   4015                 if (!secure_mode) {
   4016                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
   4017                         (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   4018                                 PROT_READ|PROT_WRITE, MAP_SHARED,
   4019                                 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   4020                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   4021                         close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4022 #ifdef USE_ION
   4023                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   4024 #endif
   4025                         DEBUG_PRINT_ERROR("Unable to mmap output buffer\n");
   4026                         return OMX_ErrorInsufficientResources;
   4027                     }
   4028                 }
   4029                 drv_ctx.ptr_outputbuffer[i].offset = 0;
   4030                 privateAppData = appData;
   4031             } else {
   4032 
   4033                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   4034                 if (!appData || !bytes ) {
   4035                     if (!secure_mode && !buffer) {
   4036                         DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
   4037                         return OMX_ErrorBadParameter;
   4038                     }
   4039                 }
   4040 
   4041                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   4042                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   4043                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   4044                 if (!pmem_list->entryList || !pmem_list->entryList->entry ||
   4045                         !pmem_list->nEntries ||
   4046                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4047                     DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
   4048                     return OMX_ErrorBadParameter;
   4049                 }
   4050                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   4051                     pmem_list->entryList->entry;
   4052                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   4053                         pmem_info->pmem_fd);
   4054                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   4055                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   4056                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   4057                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
   4058                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   4059                 privateAppData = appData;
   4060             }
   4061         m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   4062         m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   4063 
   4064         *bufferHdr = (m_out_mem_ptr + i );
   4065         if (secure_mode)
   4066             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   4067         //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   4068         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   4069                 sizeof (vdec_bufferpayload));
   4070 
   4071         DEBUG_PRINT_HIGH("\n Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   4072                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   4073                 drv_ctx.ptr_outputbuffer[i].pmem_fd );
   4074 
   4075         buf.index = i;
   4076         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4077         buf.memory = V4L2_MEMORY_USERPTR;
   4078         plane[0].length = drv_ctx.op_buf.buffer_size;
   4079         plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   4080             (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   4081         plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   4082         plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   4083         plane[0].data_offset = 0;
   4084         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   4085         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   4086             plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   4087             plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   4088 #ifdef USE_ION
   4089             plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   4090 #endif
   4091             plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   4092             plane[extra_idx].data_offset = 0;
   4093         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   4094             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
   4095             return OMX_ErrorBadParameter;
   4096         }
   4097         buf.m.planes = plane;
   4098         buf.length = drv_ctx.num_planes;
   4099 
   4100         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
   4101             DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
   4102             /*TODO: How to handle this case */
   4103             return OMX_ErrorInsufficientResources;
   4104         }
   4105 
   4106         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   4107             enum v4l2_buf_type buf_type;
   4108             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4109             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   4110                 return OMX_ErrorInsufficientResources;
   4111             } else {
   4112                 streaming[CAPTURE_PORT] = true;
   4113                 DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
   4114             }
   4115         }
   4116 
   4117         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   4118         if (m_enable_android_native_buffers) {
   4119             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   4120             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   4121         } else {
   4122             (*bufferHdr)->pBuffer = buff;
   4123         }
   4124         (*bufferHdr)->pAppPrivate = privateAppData;
   4125         BITMASK_SET(&m_out_bm_count,i);
   4126     }
   4127     return eRet;
   4128 }
   4129 
   4130 /* ======================================================================
   4131    FUNCTION
   4132    omx_vdec::use_input_heap_buffers
   4133 
   4134    DESCRIPTION
   4135    OMX Use Buffer Heap allocation method implementation.
   4136 
   4137    PARAMETERS
   4138    <TBD>.
   4139 
   4140    RETURN VALUE
   4141    OMX Error None , if everything successful.
   4142 
   4143    ========================================================================== */
   4144 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
   4145         OMX_IN OMX_HANDLETYPE            hComp,
   4146         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4147         OMX_IN OMX_U32                   port,
   4148         OMX_IN OMX_PTR                   appData,
   4149         OMX_IN OMX_U32                   bytes,
   4150         OMX_IN OMX_U8*                   buffer)
   4151 {
   4152     DEBUG_PRINT_LOW("Inside %s, %p\n", __FUNCTION__, buffer);
   4153     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4154     if (!m_inp_heap_ptr)
   4155         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   4156             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4157                     drv_ctx.ip_buf.actualcount);
   4158     if (!m_phdr_pmem_ptr)
   4159         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   4160             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4161                     drv_ctx.ip_buf.actualcount);
   4162     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
   4163         DEBUG_PRINT_ERROR("Insufficent memory");
   4164         eRet = OMX_ErrorInsufficientResources;
   4165     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
   4166         input_use_buffer = true;
   4167         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   4168         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   4169         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   4170         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   4171         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   4172         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   4173         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   4174         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   4175         DEBUG_PRINT_HIGH("\n Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   4176         if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt],
   4177                     (unsigned)NULL, (unsigned)NULL)) {
   4178             DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
   4179             return OMX_ErrorInsufficientResources;
   4180         }
   4181         m_in_alloc_cnt++;
   4182     } else {
   4183         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
   4184         eRet = OMX_ErrorInsufficientResources;
   4185     }
   4186     return eRet;
   4187 }
   4188 
   4189 /* ======================================================================
   4190    FUNCTION
   4191    omx_vdec::UseBuffer
   4192 
   4193    DESCRIPTION
   4194    OMX Use Buffer method implementation.
   4195 
   4196    PARAMETERS
   4197    <TBD>.
   4198 
   4199    RETURN VALUE
   4200    OMX Error None , if everything successful.
   4201 
   4202    ========================================================================== */
   4203 OMX_ERRORTYPE  omx_vdec::use_buffer(
   4204         OMX_IN OMX_HANDLETYPE            hComp,
   4205         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4206         OMX_IN OMX_U32                   port,
   4207         OMX_IN OMX_PTR                   appData,
   4208         OMX_IN OMX_U32                   bytes,
   4209         OMX_IN OMX_U8*                   buffer)
   4210 {
   4211     OMX_ERRORTYPE error = OMX_ErrorNone;
   4212     struct vdec_setbuffer_cmd setbuffers;
   4213 
   4214     if (bufferHdr == NULL || bytes == 0) {
   4215         if (!secure_mode && buffer == NULL) {
   4216             DEBUG_PRINT_ERROR("bad param 0x%p %ld 0x%p",bufferHdr, bytes, buffer);
   4217             return OMX_ErrorBadParameter;
   4218         }
   4219     }
   4220     if (m_state == OMX_StateInvalid) {
   4221         DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
   4222         return OMX_ErrorInvalidState;
   4223     }
   4224     if (port == OMX_CORE_INPUT_PORT_INDEX)
   4225         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   4226     else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
   4227         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
   4228     else {
   4229         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   4230         error = OMX_ErrorBadPortIndex;
   4231     }
   4232     DEBUG_PRINT_LOW("Use Buffer: port %lu, buffer %p, eRet %d", port, *bufferHdr, error);
   4233     if (error == OMX_ErrorNone) {
   4234         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   4235             // Send the callback now
   4236             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   4237             post_event(OMX_CommandStateSet,OMX_StateIdle,
   4238                     OMX_COMPONENT_GENERATE_EVENT);
   4239         }
   4240         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   4241                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   4242             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   4243             post_event(OMX_CommandPortEnable,
   4244                     OMX_CORE_INPUT_PORT_INDEX,
   4245                     OMX_COMPONENT_GENERATE_EVENT);
   4246         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   4247                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   4248             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   4249             post_event(OMX_CommandPortEnable,
   4250                     OMX_CORE_OUTPUT_PORT_INDEX,
   4251                     OMX_COMPONENT_GENERATE_EVENT);
   4252         }
   4253     }
   4254     return error;
   4255 }
   4256 
   4257 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
   4258         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
   4259 {
   4260     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
   4261         if (m_inp_heap_ptr[bufferindex].pBuffer)
   4262             free(m_inp_heap_ptr[bufferindex].pBuffer);
   4263         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
   4264     }
   4265     if (pmem_bufferHdr)
   4266         free_input_buffer(pmem_bufferHdr);
   4267     return OMX_ErrorNone;
   4268 }
   4269 
   4270 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   4271 {
   4272     unsigned int index = 0;
   4273     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   4274         return OMX_ErrorBadParameter;
   4275     }
   4276 
   4277     index = bufferHdr - m_inp_mem_ptr;
   4278     DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
   4279 
   4280     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   4281         DEBUG_PRINT_LOW("\n Free Input Buffer index = %d",index);
   4282         if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
   4283             struct vdec_setbuffer_cmd setbuffers;
   4284             setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   4285             memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   4286                     sizeof (vdec_bufferpayload));
   4287             if (!secure_mode) {
   4288                 DEBUG_PRINT_LOW("\n unmap the input buffer fd=%d",
   4289                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
   4290                 DEBUG_PRINT_LOW("\n unmap the input buffer size=%d  address = %p",
   4291                         drv_ctx.ptr_inputbuffer[index].mmaped_size,
   4292                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
   4293                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   4294                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
   4295             }
   4296             close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
   4297             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   4298             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
   4299                 free(m_desc_buffer_ptr[index].buf_addr);
   4300                 m_desc_buffer_ptr[index].buf_addr = NULL;
   4301                 m_desc_buffer_ptr[index].desc_data_size = 0;
   4302             }
   4303 #ifdef USE_ION
   4304             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   4305 #endif
   4306         }
   4307     }
   4308 
   4309     return OMX_ErrorNone;
   4310 }
   4311 
   4312 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   4313 {
   4314     unsigned int index = 0;
   4315 
   4316     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   4317         return OMX_ErrorBadParameter;
   4318     }
   4319 
   4320     index = bufferHdr - m_out_mem_ptr;
   4321     DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d",index);
   4322 
   4323     if (index < drv_ctx.op_buf.actualcount
   4324             && drv_ctx.ptr_outputbuffer) {
   4325         DEBUG_PRINT_LOW("\n Free ouput Buffer index = %d addr = %p", index,
   4326                 drv_ctx.ptr_outputbuffer[index].bufferaddr);
   4327 
   4328         struct vdec_setbuffer_cmd setbuffers;
   4329         setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   4330         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   4331                 sizeof (vdec_bufferpayload));
   4332 
   4333         if (!dynamic_buf_mode) {
   4334 #ifdef _ANDROID_
   4335             if (m_enable_android_native_buffers) {
   4336                 if (!secure_mode) {
   4337                     if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   4338                         munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   4339                                 drv_ctx.ptr_outputbuffer[index].mmaped_size);
   4340                     }
   4341                 }
   4342                 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   4343             } else {
   4344 #endif
   4345                 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
   4346                     if (!secure_mode) {
   4347                         DEBUG_PRINT_LOW("\n unmap the output buffer fd = %d",
   4348                                 drv_ctx.ptr_outputbuffer[0].pmem_fd);
   4349                         DEBUG_PRINT_LOW("\n unmap the ouput buffer size=%d  address = %p",
   4350                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
   4351                                 drv_ctx.ptr_outputbuffer[0].bufferaddr);
   4352                         munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
   4353                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
   4354                     }
   4355                     close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
   4356                     drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
   4357 #ifdef USE_ION
   4358                     free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
   4359 #endif
   4360                 }
   4361 #ifdef _ANDROID_
   4362             }
   4363 #endif
   4364         } //!dynamic_buf_mode
   4365         if (release_output_done()) {
   4366             free_extradata();
   4367         }
   4368     }
   4369 
   4370     return OMX_ErrorNone;
   4371 
   4372 }
   4373 
   4374 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   4375         OMX_BUFFERHEADERTYPE **bufferHdr,
   4376         OMX_U32              port,
   4377         OMX_PTR              appData,
   4378         OMX_U32              bytes)
   4379 {
   4380     OMX_BUFFERHEADERTYPE *input = NULL;
   4381     unsigned char *buf_addr = NULL;
   4382     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4383     unsigned   i = 0;
   4384 
   4385     /* Sanity Check*/
   4386     if (bufferHdr == NULL) {
   4387         return OMX_ErrorBadParameter;
   4388     }
   4389 
   4390     if (m_inp_heap_ptr == NULL) {
   4391         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   4392                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4393                          drv_ctx.ip_buf.actualcount);
   4394         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   4395                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4396                           drv_ctx.ip_buf.actualcount);
   4397 
   4398         if (m_inp_heap_ptr == NULL) {
   4399             DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
   4400             return OMX_ErrorInsufficientResources;
   4401         }
   4402     }
   4403 
   4404     /*Find a Free index*/
   4405     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   4406         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
   4407             DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
   4408             break;
   4409         }
   4410     }
   4411 
   4412     if (i < drv_ctx.ip_buf.actualcount) {
   4413         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   4414 
   4415         if (buf_addr == NULL) {
   4416             return OMX_ErrorInsufficientResources;
   4417         }
   4418 
   4419         *bufferHdr = (m_inp_heap_ptr + i);
   4420         input = *bufferHdr;
   4421         BITMASK_SET(&m_heap_inp_bm_count,i);
   4422 
   4423         input->pBuffer           = (OMX_U8 *)buf_addr;
   4424         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   4425         input->nVersion.nVersion = OMX_SPEC_VERSION;
   4426         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   4427         input->pAppPrivate       = appData;
   4428         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   4429         DEBUG_PRINT_LOW("\n Address of Heap Buffer %p",*bufferHdr );
   4430         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   4431         DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   4432         /*Add the Buffers to freeq*/
   4433         if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[i],
   4434                     (unsigned)NULL, (unsigned)NULL)) {
   4435             DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
   4436             return OMX_ErrorInsufficientResources;
   4437         }
   4438     } else {
   4439         return OMX_ErrorBadParameter;
   4440     }
   4441 
   4442     return eRet;
   4443 
   4444 }
   4445 
   4446 
   4447 /* ======================================================================
   4448    FUNCTION
   4449    omx_vdec::AllocateInputBuffer
   4450 
   4451    DESCRIPTION
   4452    Helper function for allocate buffer in the input pin
   4453 
   4454    PARAMETERS
   4455    None.
   4456 
   4457    RETURN VALUE
   4458    true/false
   4459 
   4460    ========================================================================== */
   4461 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   4462         OMX_IN OMX_HANDLETYPE            hComp,
   4463         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4464         OMX_IN OMX_U32                   port,
   4465         OMX_IN OMX_PTR                   appData,
   4466         OMX_IN OMX_U32                   bytes)
   4467 {
   4468 
   4469     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4470     struct vdec_setbuffer_cmd setbuffers;
   4471     OMX_BUFFERHEADERTYPE *input = NULL;
   4472     unsigned   i = 0;
   4473     unsigned char *buf_addr = NULL;
   4474     int pmem_fd = -1;
   4475 
   4476     if (bytes != drv_ctx.ip_buf.buffer_size) {
   4477         DEBUG_PRINT_LOW("\n Requested Size is wrong %lu epected is %d",
   4478                 bytes, drv_ctx.ip_buf.buffer_size);
   4479         return OMX_ErrorBadParameter;
   4480     }
   4481 
   4482     if (!m_inp_mem_ptr) {
   4483         DEBUG_PRINT_HIGH("\n Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
   4484                 drv_ctx.ip_buf.actualcount,
   4485                 drv_ctx.ip_buf.buffer_size);
   4486 
   4487         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   4488                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   4489 
   4490         if (m_inp_mem_ptr == NULL) {
   4491             return OMX_ErrorInsufficientResources;
   4492         }
   4493 
   4494         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   4495                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   4496 
   4497         if (drv_ctx.ptr_inputbuffer == NULL) {
   4498             return OMX_ErrorInsufficientResources;
   4499         }
   4500 #ifdef USE_ION
   4501         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   4502                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   4503 
   4504         if (drv_ctx.ip_buf_ion_info == NULL) {
   4505             return OMX_ErrorInsufficientResources;
   4506         }
   4507 #endif
   4508 
   4509         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   4510             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   4511 #ifdef USE_ION
   4512             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   4513 #endif
   4514         }
   4515     }
   4516 
   4517     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   4518         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   4519             DEBUG_PRINT_LOW("\n Free Input Buffer Index %d",i);
   4520             break;
   4521         }
   4522     }
   4523 
   4524     if (i < drv_ctx.ip_buf.actualcount) {
   4525         struct v4l2_buffer buf;
   4526         struct v4l2_plane plane;
   4527         int rc;
   4528         DEBUG_PRINT_LOW("\n Allocate input Buffer");
   4529 #ifdef USE_ION
   4530         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   4531                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   4532                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   4533                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
   4534         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   4535             return OMX_ErrorInsufficientResources;
   4536         }
   4537         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   4538 #else
   4539         pmem_fd = open (MEM_DEVICE,O_RDWR);
   4540 
   4541         if (pmem_fd < 0) {
   4542             DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
   4543             return OMX_ErrorInsufficientResources;
   4544         }
   4545 
   4546         if (pmem_fd == 0) {
   4547             pmem_fd = open (MEM_DEVICE,O_RDWR);
   4548 
   4549             if (pmem_fd < 0) {
   4550                 DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
   4551                 return OMX_ErrorInsufficientResources;
   4552             }
   4553         }
   4554 
   4555         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   4556                     drv_ctx.ip_buf.alignment)) {
   4557             DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   4558             close(pmem_fd);
   4559             return OMX_ErrorInsufficientResources;
   4560         }
   4561 #endif
   4562         if (!secure_mode) {
   4563             buf_addr = (unsigned char *)mmap(NULL,
   4564                     drv_ctx.ip_buf.buffer_size,
   4565                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   4566 
   4567             if (buf_addr == MAP_FAILED) {
   4568                 close(pmem_fd);
   4569 #ifdef USE_ION
   4570                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   4571 #endif
   4572                 DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
   4573                 return OMX_ErrorInsufficientResources;
   4574             }
   4575         }
   4576         *bufferHdr = (m_inp_mem_ptr + i);
   4577         if (secure_mode)
   4578             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   4579         else
   4580             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   4581         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   4582         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   4583         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   4584         drv_ctx.ptr_inputbuffer [i].offset = 0;
   4585 
   4586 
   4587         buf.index = i;
   4588         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4589         buf.memory = V4L2_MEMORY_USERPTR;
   4590         plane.bytesused = 0;
   4591         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   4592         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   4593         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   4594         plane.reserved[1] = 0;
   4595         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   4596         buf.m.planes = &plane;
   4597         buf.length = 1;
   4598 
   4599         DEBUG_PRINT_LOW("\n Set the input Buffer Idx: %d Addr: %p", i,
   4600                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   4601 
   4602         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   4603 
   4604         if (rc) {
   4605             DEBUG_PRINT_ERROR("Failed to prepare bufs\n");
   4606             /*TODO: How to handle this case */
   4607             return OMX_ErrorInsufficientResources;
   4608         }
   4609 
   4610         input = *bufferHdr;
   4611         BITMASK_SET(&m_inp_bm_count,i);
   4612         DEBUG_PRINT_LOW("\n Buffer address %p of pmem",*bufferHdr);
   4613         if (secure_mode)
   4614             input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
   4615         else
   4616             input->pBuffer           = (OMX_U8 *)buf_addr;
   4617         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   4618         input->nVersion.nVersion = OMX_SPEC_VERSION;
   4619         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   4620         input->pAppPrivate       = appData;
   4621         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   4622         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   4623 
   4624         if (drv_ctx.disable_dmx) {
   4625             eRet = allocate_desc_buffer(i);
   4626         }
   4627     } else {
   4628         DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
   4629         eRet = OMX_ErrorInsufficientResources;
   4630     }
   4631     return eRet;
   4632 }
   4633 
   4634 
   4635 /* ======================================================================
   4636    FUNCTION
   4637    omx_vdec::AllocateOutputBuffer
   4638 
   4639    DESCRIPTION
   4640    Helper fn for AllocateBuffer in the output pin
   4641 
   4642    PARAMETERS
   4643    <TBD>.
   4644 
   4645    RETURN VALUE
   4646    OMX Error None if everything went well.
   4647 
   4648    ========================================================================== */
   4649 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   4650         OMX_IN OMX_HANDLETYPE            hComp,
   4651         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4652         OMX_IN OMX_U32                   port,
   4653         OMX_IN OMX_PTR                   appData,
   4654         OMX_IN OMX_U32                   bytes)
   4655 {
   4656     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4657     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   4658     unsigned                         i= 0; // Temporary counter
   4659     struct vdec_setbuffer_cmd setbuffers;
   4660     int extra_idx = 0;
   4661 #ifdef USE_ION
   4662     int ion_device_fd =-1;
   4663     struct ion_allocation_data ion_alloc_data;
   4664     struct ion_fd_data fd_ion_data;
   4665 #endif
   4666     if (!m_out_mem_ptr) {
   4667         DEBUG_PRINT_HIGH("\n Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
   4668                 drv_ctx.op_buf.actualcount,
   4669                 drv_ctx.op_buf.buffer_size);
   4670         int nBufHdrSize        = 0;
   4671         int nPlatformEntrySize = 0;
   4672         int nPlatformListSize  = 0;
   4673         int nPMEMInfoSize = 0;
   4674         int pmem_fd = -1;
   4675         unsigned char *pmem_baseaddress = NULL;
   4676 
   4677         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   4678         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   4679         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   4680 
   4681         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",
   4682                 drv_ctx.op_buf.actualcount);
   4683         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   4684             sizeof(OMX_BUFFERHEADERTYPE);
   4685 
   4686         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   4687             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   4688         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   4689             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   4690         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   4691             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   4692 
   4693         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
   4694                 sizeof(OMX_BUFFERHEADERTYPE),
   4695                 nPMEMInfoSize,
   4696                 nPlatformListSize);
   4697         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d \n",nPlatformEntrySize,
   4698                 drv_ctx.op_buf.actualcount);
   4699 #ifdef USE_ION
   4700         ion_device_fd = alloc_map_ion_memory(
   4701                 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
   4702                 drv_ctx.op_buf.alignment,
   4703                 &ion_alloc_data, &fd_ion_data, secure_mode ? ION_SECURE : 0);
   4704         if (ion_device_fd < 0) {
   4705             return OMX_ErrorInsufficientResources;
   4706         }
   4707         pmem_fd = fd_ion_data.fd;
   4708 #else
   4709         pmem_fd = open (MEM_DEVICE,O_RDWR);
   4710 
   4711         if (pmem_fd < 0) {
   4712             DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
   4713                     drv_ctx.op_buf.buffer_size);
   4714             return OMX_ErrorInsufficientResources;
   4715         }
   4716 
   4717         if (pmem_fd == 0) {
   4718             pmem_fd = open (MEM_DEVICE,O_RDWR);
   4719 
   4720             if (pmem_fd < 0) {
   4721                 DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
   4722                         drv_ctx.op_buf.buffer_size);
   4723                 return OMX_ErrorInsufficientResources;
   4724             }
   4725         }
   4726 
   4727         if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
   4728                     drv_ctx.op_buf.actualcount,
   4729                     drv_ctx.op_buf.alignment)) {
   4730             DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
   4731             close(pmem_fd);
   4732             return OMX_ErrorInsufficientResources;
   4733         }
   4734 #endif
   4735         if (!secure_mode) {
   4736             pmem_baseaddress = (unsigned char *)mmap(NULL,
   4737                     (drv_ctx.op_buf.buffer_size *
   4738                      drv_ctx.op_buf.actualcount),
   4739                     PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   4740             if (pmem_baseaddress == MAP_FAILED) {
   4741                 DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
   4742                         drv_ctx.op_buf.buffer_size);
   4743                 close(pmem_fd);
   4744 #ifdef USE_ION
   4745                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   4746 #endif
   4747                 return OMX_ErrorInsufficientResources;
   4748             }
   4749         }
   4750         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   4751         // Alloc mem for platform specific info
   4752         char *pPtr=NULL;
   4753         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   4754                 nPMEMInfoSize,1);
   4755         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   4756                        calloc (sizeof(struct vdec_bufferpayload),
   4757                                drv_ctx.op_buf.actualcount);
   4758         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   4759                      calloc (sizeof (struct vdec_output_frameinfo),
   4760                              drv_ctx.op_buf.actualcount);
   4761 #ifdef USE_ION
   4762         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   4763                       calloc (sizeof(struct vdec_ion),
   4764                               drv_ctx.op_buf.actualcount);
   4765 #endif
   4766 
   4767         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   4768                 && drv_ctx.ptr_respbuffer) {
   4769             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   4770                 (drv_ctx.op_buf.buffer_size *
   4771                  drv_ctx.op_buf.actualcount);
   4772             bufHdr          =  m_out_mem_ptr;
   4773             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   4774             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   4775                 (((char *) m_platform_list)  + nPlatformListSize);
   4776             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   4777                 (((char *) m_platform_entry) + nPlatformEntrySize);
   4778             pPlatformList   = m_platform_list;
   4779             pPlatformEntry  = m_platform_entry;
   4780             pPMEMInfo       = m_pmem_info;
   4781 
   4782             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   4783 
   4784             // Settting the entire storage nicely
   4785             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr, m_out_mem_ptr,pPlatformEntry);
   4786             DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
   4787             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   4788                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   4789                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   4790                 // Set the values when we determine the right HxW param
   4791                 bufHdr->nAllocLen          = bytes;
   4792                 bufHdr->nFilledLen         = 0;
   4793                 bufHdr->pAppPrivate        = appData;
   4794                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   4795                 // Platform specific PMEM Information
   4796                 // Initialize the Platform Entry
   4797                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d\n",i);
   4798                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   4799                 pPlatformEntry->entry      = pPMEMInfo;
   4800                 // Initialize the Platform List
   4801                 pPlatformList->nEntries    = 1;
   4802                 pPlatformList->entryList   = pPlatformEntry;
   4803                 // Keep pBuffer NULL till vdec is opened
   4804                 bufHdr->pBuffer            = NULL;
   4805                 bufHdr->nOffset            = 0;
   4806 
   4807                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   4808                 pPMEMInfo->pmem_fd = 0;
   4809                 bufHdr->pPlatformPrivate = pPlatformList;
   4810 
   4811                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   4812                 m_pmem_info[i].pmem_fd = pmem_fd;
   4813 #ifdef USE_ION
   4814                 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
   4815                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
   4816                 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
   4817 #endif
   4818 
   4819                 /*Create a mapping between buffers*/
   4820                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   4821                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   4822                                     &drv_ctx.ptr_outputbuffer[i];
   4823                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
   4824                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   4825                     pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
   4826 
   4827                 DEBUG_PRINT_LOW("\n pmem_fd = %d offset = %d address = %p",
   4828                         pmem_fd, drv_ctx.ptr_outputbuffer[i].offset,
   4829                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   4830                 // Move the buffer and buffer header pointers
   4831                 bufHdr++;
   4832                 pPMEMInfo++;
   4833                 pPlatformEntry++;
   4834                 pPlatformList++;
   4835             }
   4836         } else {
   4837             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
   4838                     m_out_mem_ptr, pPtr);
   4839             if (m_out_mem_ptr) {
   4840                 free(m_out_mem_ptr);
   4841                 m_out_mem_ptr = NULL;
   4842             }
   4843             if (pPtr) {
   4844                 free(pPtr);
   4845                 pPtr = NULL;
   4846             }
   4847             if (drv_ctx.ptr_outputbuffer) {
   4848                 free(drv_ctx.ptr_outputbuffer);
   4849                 drv_ctx.ptr_outputbuffer = NULL;
   4850             }
   4851             if (drv_ctx.ptr_respbuffer) {
   4852                 free(drv_ctx.ptr_respbuffer);
   4853                 drv_ctx.ptr_respbuffer = NULL;
   4854             }
   4855 #ifdef USE_ION
   4856             if (drv_ctx.op_buf_ion_info) {
   4857                 DEBUG_PRINT_LOW("\n Free o/p ion context");
   4858                 free(drv_ctx.op_buf_ion_info);
   4859                 drv_ctx.op_buf_ion_info = NULL;
   4860             }
   4861 #endif
   4862             eRet =  OMX_ErrorInsufficientResources;
   4863         }
   4864         if (eRet == OMX_ErrorNone)
   4865             eRet = allocate_extradata();
   4866     }
   4867 
   4868     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   4869         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   4870             DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
   4871             break;
   4872         }
   4873     }
   4874 
   4875     if (eRet == OMX_ErrorNone) {
   4876         if (i < drv_ctx.op_buf.actualcount) {
   4877             struct v4l2_buffer buf;
   4878             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   4879             int rc;
   4880             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   4881 
   4882             drv_ctx.ptr_outputbuffer[i].buffer_len =
   4883                 drv_ctx.op_buf.buffer_size;
   4884 
   4885             *bufferHdr = (m_out_mem_ptr + i );
   4886             if (secure_mode) {
   4887                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   4888             }
   4889             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   4890 
   4891             buf.index = i;
   4892             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4893             buf.memory = V4L2_MEMORY_USERPTR;
   4894             plane[0].length = drv_ctx.op_buf.buffer_size;
   4895             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   4896                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   4897 #ifdef USE_ION
   4898             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   4899 #endif
   4900             plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   4901             plane[0].data_offset = 0;
   4902             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   4903             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   4904                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   4905                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   4906 #ifdef USE_ION
   4907                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   4908 #endif
   4909                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   4910                 plane[extra_idx].data_offset = 0;
   4911             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   4912                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d\n", extra_idx);
   4913                 return OMX_ErrorBadParameter;
   4914             }
   4915             buf.m.planes = plane;
   4916             buf.length = drv_ctx.num_planes;
   4917             DEBUG_PRINT_LOW("\n Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   4918             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   4919             if (rc) {
   4920                 /*TODO: How to handle this case */
   4921                 return OMX_ErrorInsufficientResources;
   4922             }
   4923 
   4924             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   4925                 enum v4l2_buf_type buf_type;
   4926                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4927                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   4928                 if (rc) {
   4929                     return OMX_ErrorInsufficientResources;
   4930                 } else {
   4931                     streaming[CAPTURE_PORT] = true;
   4932                     DEBUG_PRINT_LOW("\n STREAMON Successful \n ");
   4933                 }
   4934             }
   4935 
   4936             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   4937             (*bufferHdr)->pAppPrivate = appData;
   4938             BITMASK_SET(&m_out_bm_count,i);
   4939         } else {
   4940             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient \n");
   4941             eRet = OMX_ErrorInsufficientResources;
   4942         }
   4943     }
   4944 
   4945     return eRet;
   4946 }
   4947 
   4948 
   4949 // AllocateBuffer  -- API Call
   4950 /* ======================================================================
   4951    FUNCTION
   4952    omx_vdec::AllocateBuffer
   4953 
   4954    DESCRIPTION
   4955    Returns zero if all the buffers released..
   4956 
   4957    PARAMETERS
   4958    None.
   4959 
   4960    RETURN VALUE
   4961    true/false
   4962 
   4963    ========================================================================== */
   4964 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   4965         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4966         OMX_IN OMX_U32                        port,
   4967         OMX_IN OMX_PTR                     appData,
   4968         OMX_IN OMX_U32                       bytes)
   4969 {
   4970     unsigned i = 0;
   4971     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   4972 
   4973     DEBUG_PRINT_LOW("\n Allocate buffer on port %d \n", (int)port);
   4974     if (m_state == OMX_StateInvalid) {
   4975         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
   4976         return OMX_ErrorInvalidState;
   4977     }
   4978 
   4979     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   4980         if (arbitrary_bytes) {
   4981             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   4982         } else {
   4983             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   4984         }
   4985     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   4986         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   4987                 appData,bytes);
   4988     } else {
   4989         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
   4990         eRet = OMX_ErrorBadPortIndex;
   4991     }
   4992     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   4993     if (eRet == OMX_ErrorNone) {
   4994         if (allocate_done()) {
   4995             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   4996                 // Send the callback now
   4997                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   4998                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   4999                         OMX_COMPONENT_GENERATE_EVENT);
   5000             }
   5001         }
   5002         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   5003             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   5004                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5005                 post_event(OMX_CommandPortEnable,
   5006                         OMX_CORE_INPUT_PORT_INDEX,
   5007                         OMX_COMPONENT_GENERATE_EVENT);
   5008             }
   5009         }
   5010         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   5011             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   5012                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5013                 post_event(OMX_CommandPortEnable,
   5014                         OMX_CORE_OUTPUT_PORT_INDEX,
   5015                         OMX_COMPONENT_GENERATE_EVENT);
   5016             }
   5017         }
   5018     }
   5019     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
   5020     return eRet;
   5021 }
   5022 
   5023 // Free Buffer - API call
   5024 /* ======================================================================
   5025    FUNCTION
   5026    omx_vdec::FreeBuffer
   5027 
   5028    DESCRIPTION
   5029 
   5030    PARAMETERS
   5031    None.
   5032 
   5033    RETURN VALUE
   5034    true/false
   5035 
   5036    ========================================================================== */
   5037 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   5038         OMX_IN OMX_U32                 port,
   5039         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5040 {
   5041     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5042     unsigned int nPortIndex;
   5043     DEBUG_PRINT_LOW("In for decoder free_buffer \n");
   5044 
   5045     if (m_state == OMX_StateIdle &&
   5046             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   5047         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
   5048     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   5049             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   5050         DEBUG_PRINT_LOW("Free Buffer while port %lu disabled\n", port);
   5051     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   5052                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   5053             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   5054              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   5055         DEBUG_PRINT_LOW("Free Buffer while port %d enable pending\n", port);
   5056     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   5057         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
   5058         post_event(OMX_EventError,
   5059                 OMX_ErrorPortUnpopulated,
   5060                 OMX_COMPONENT_GENERATE_EVENT);
   5061 
   5062         return OMX_ErrorIncorrectStateOperation;
   5063     } else if (m_state != OMX_StateInvalid) {
   5064         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
   5065         post_event(OMX_EventError,
   5066                 OMX_ErrorPortUnpopulated,
   5067                 OMX_COMPONENT_GENERATE_EVENT);
   5068     }
   5069 
   5070     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   5071         /*Check if arbitrary bytes*/
   5072         if (!arbitrary_bytes && !input_use_buffer)
   5073             nPortIndex = buffer - m_inp_mem_ptr;
   5074         else
   5075             nPortIndex = buffer - m_inp_heap_ptr;
   5076 
   5077         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d \n", nPortIndex);
   5078         if (nPortIndex < drv_ctx.ip_buf.actualcount) {
   5079             // Clear the bit associated with it.
   5080             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   5081             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   5082             if (input_use_buffer == true) {
   5083 
   5084                 DEBUG_PRINT_LOW("\n Free pmem Buffer index %d",nPortIndex);
   5085                 if (m_phdr_pmem_ptr)
   5086                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   5087             } else {
   5088                 if (arbitrary_bytes) {
   5089                     if (m_phdr_pmem_ptr)
   5090                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   5091                     else
   5092                         free_input_buffer(nPortIndex,NULL);
   5093                 } else
   5094                     free_input_buffer(buffer);
   5095             }
   5096             m_inp_bPopulated = OMX_FALSE;
   5097             if(release_input_done())
   5098                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   5099             /*Free the Buffer Header*/
   5100             if (release_input_done()) {
   5101                 DEBUG_PRINT_HIGH("\n ALL input buffers are freed/released");
   5102                 free_input_buffer_header();
   5103             }
   5104         } else {
   5105             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
   5106             eRet = OMX_ErrorBadPortIndex;
   5107         }
   5108 
   5109         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   5110                 && release_input_done()) {
   5111             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   5112             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   5113             post_event(OMX_CommandPortDisable,
   5114                     OMX_CORE_INPUT_PORT_INDEX,
   5115                     OMX_COMPONENT_GENERATE_EVENT);
   5116         }
   5117     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   5118         // check if the buffer is valid
   5119         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   5120         if (nPortIndex < drv_ctx.op_buf.actualcount) {
   5121             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d \n", nPortIndex);
   5122             // Clear the bit associated with it.
   5123             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   5124             m_out_bPopulated = OMX_FALSE;
   5125             client_buffers.free_output_buffer (buffer);
   5126 
   5127             if(release_output_done()) {
   5128                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   5129             }
   5130             if (release_output_done()) {
   5131                 free_output_buffer_header();
   5132             }
   5133         } else {
   5134             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
   5135             eRet = OMX_ErrorBadPortIndex;
   5136         }
   5137         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   5138                 && release_output_done()) {
   5139             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
   5140 
   5141             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
   5142             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   5143 #ifdef _ANDROID_ICS_
   5144             if (m_enable_android_native_buffers) {
   5145                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   5146                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   5147             }
   5148 #endif
   5149 
   5150             post_event(OMX_CommandPortDisable,
   5151                     OMX_CORE_OUTPUT_PORT_INDEX,
   5152                     OMX_COMPONENT_GENERATE_EVENT);
   5153         }
   5154     } else {
   5155         eRet = OMX_ErrorBadPortIndex;
   5156     }
   5157     if ((eRet == OMX_ErrorNone) &&
   5158             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   5159         if (release_done()) {
   5160             // Send the callback now
   5161             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   5162             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   5163                     OMX_COMPONENT_GENERATE_EVENT);
   5164         }
   5165     }
   5166     return eRet;
   5167 }
   5168 
   5169 
   5170 /* ======================================================================
   5171    FUNCTION
   5172    omx_vdec::EmptyThisBuffer
   5173 
   5174    DESCRIPTION
   5175    This routine is used to push the encoded video frames to
   5176    the video decoder.
   5177 
   5178    PARAMETERS
   5179    None.
   5180 
   5181    RETURN VALUE
   5182    OMX Error None if everything went successful.
   5183 
   5184    ========================================================================== */
   5185 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   5186         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5187 {
   5188     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   5189     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   5190 
   5191     if (m_state == OMX_StateInvalid) {
   5192         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
   5193         return OMX_ErrorInvalidState;
   5194     }
   5195 
   5196     if (buffer == NULL) {
   5197         DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
   5198         return OMX_ErrorBadParameter;
   5199     }
   5200 
   5201     if (!m_inp_bEnabled) {
   5202         DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
   5203         return OMX_ErrorIncorrectStateOperation;
   5204     }
   5205 
   5206     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   5207         DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %lu", buffer->nInputPortIndex);
   5208         return OMX_ErrorBadPortIndex;
   5209     }
   5210 
   5211 #ifdef _ANDROID_
   5212     if (iDivXDrmDecrypt) {
   5213         OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
   5214         if (drmErr != OMX_ErrorNone) {
   5215             // this error can be ignored
   5216             DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
   5217         }
   5218     }
   5219 #endif //_ANDROID_
   5220     if (perf_flag) {
   5221         if (!latency) {
   5222             dec_time.stop();
   5223             latency = dec_time.processing_time_us();
   5224             dec_time.start();
   5225         }
   5226     }
   5227 
   5228     if (arbitrary_bytes) {
   5229         nBufferIndex = buffer - m_inp_heap_ptr;
   5230     } else {
   5231         if (input_use_buffer == true) {
   5232             nBufferIndex = buffer - m_inp_heap_ptr;
   5233             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   5234             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   5235             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   5236             buffer = &m_inp_mem_ptr[nBufferIndex];
   5237             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %lu",
   5238                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
   5239         } else {
   5240             nBufferIndex = buffer - m_inp_mem_ptr;
   5241         }
   5242     }
   5243 
   5244     if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
   5245         DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
   5246         return OMX_ErrorBadParameter;
   5247     }
   5248 
   5249     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   5250         codec_config_flag = true;
   5251         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   5252     }
   5253 
   5254     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
   5255             buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
   5256     if (arbitrary_bytes) {
   5257         post_event ((unsigned)hComp,(unsigned)buffer,
   5258                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   5259     } else {
   5260         if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
   5261             set_frame_rate(buffer->nTimeStamp);
   5262         post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
   5263     }
   5264     return OMX_ErrorNone;
   5265 }
   5266 
   5267 /* ======================================================================
   5268    FUNCTION
   5269    omx_vdec::empty_this_buffer_proxy
   5270 
   5271    DESCRIPTION
   5272    This routine is used to push the encoded video frames to
   5273    the video decoder.
   5274 
   5275    PARAMETERS
   5276    None.
   5277 
   5278    RETURN VALUE
   5279    OMX Error None if everything went successful.
   5280 
   5281    ========================================================================== */
   5282 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
   5283         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5284 {
   5285     int push_cnt = 0,i=0;
   5286     unsigned nPortIndex = 0;
   5287     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5288     struct vdec_input_frameinfo frameinfo;
   5289     struct vdec_bufferpayload *temp_buffer;
   5290     struct vdec_seqheader seq_header;
   5291     bool port_setting_changed = true;
   5292     bool not_coded_vop = false;
   5293 
   5294     /*Should we generate a Aync error event*/
   5295     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   5296         DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
   5297         return OMX_ErrorBadParameter;
   5298     }
   5299 
   5300     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   5301 
   5302     if (nPortIndex > drv_ctx.ip_buf.actualcount) {
   5303         DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   5304                 nPortIndex);
   5305         return OMX_ErrorBadParameter;
   5306     }
   5307 
   5308     pending_input_buffers++;
   5309 
   5310     /* return zero length and not an EOS buffer */
   5311     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   5312             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   5313         DEBUG_PRINT_HIGH("\n return zero legth buffer");
   5314         post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
   5315                 OMX_COMPONENT_GENERATE_EBD);
   5316         return OMX_ErrorNone;
   5317     }
   5318 
   5319 
   5320     if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
   5321         mp4StreamType psBits;
   5322         psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
   5323         psBits.numBytes = buffer->nFilledLen;
   5324         mp4_headerparser.parseHeader(&psBits);
   5325         not_coded_vop = mp4_headerparser.is_notcodec_vop(
   5326                 (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   5327         if (not_coded_vop) {
   5328             DEBUG_PRINT_HIGH("\n Found Not coded vop len %lu frame number %u",
   5329                     buffer->nFilledLen,frame_count);
   5330             if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   5331                 DEBUG_PRINT_HIGH("\n Eos and Not coded Vop set len to zero");
   5332                 not_coded_vop = false;
   5333                 buffer->nFilledLen = 0;
   5334             }
   5335         }
   5336     }
   5337 
   5338     if (input_flush_progress == true
   5339 
   5340             || not_coded_vop
   5341 
   5342        ) {
   5343         DEBUG_PRINT_LOW("\n Flush in progress return buffer ");
   5344         post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
   5345                 OMX_COMPONENT_GENERATE_EBD);
   5346         return OMX_ErrorNone;
   5347     }
   5348 
   5349     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   5350 
   5351     if ((temp_buffer -  drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
   5352         return OMX_ErrorBadParameter;
   5353     }
   5354     /* If its first frame, H264 codec and reject is true, then parse the nal
   5355        and get the profile. Based on this, reject the clip playback */
   5356     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   5357             m_reject_avc_1080p_mp) {
   5358         first_frame = 1;
   5359         DEBUG_PRINT_ERROR("\nParse nal to get the profile");
   5360         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   5361                 NALU_TYPE_SPS);
   5362         m_profile = h264_parser->get_profile();
   5363         ret = is_video_session_supported();
   5364         if (ret) {
   5365             post_event ((unsigned int)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   5366             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   5367             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   5368             m_state = OMX_StateInvalid;
   5369             return OMX_ErrorNone;
   5370         }
   5371     }
   5372 
   5373     DEBUG_PRINT_LOW("\n ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   5374     /*for use buffer we need to memcpy the data*/
   5375     temp_buffer->buffer_len = buffer->nFilledLen;
   5376 
   5377     if (input_use_buffer) {
   5378         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   5379             if (arbitrary_bytes) {
   5380                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   5381             } else {
   5382                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   5383                         buffer->nFilledLen);
   5384             }
   5385         } else {
   5386             return OMX_ErrorBadParameter;
   5387         }
   5388 
   5389     }
   5390 
   5391     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   5392     frameinfo.client_data = (void *) buffer;
   5393     frameinfo.datalen = temp_buffer->buffer_len;
   5394     frameinfo.flags = 0;
   5395     frameinfo.offset = buffer->nOffset;
   5396     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   5397     frameinfo.pmem_offset = temp_buffer->offset;
   5398     frameinfo.timestamp = buffer->nTimeStamp;
   5399     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   5400         DEBUG_PRINT_LOW("ETB: dmx enabled");
   5401         if (m_demux_entries == 0) {
   5402             extract_demux_addr_offsets(buffer);
   5403         }
   5404 
   5405         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%lu",m_demux_entries);
   5406         handle_demux_data(buffer);
   5407         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   5408         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   5409     } else {
   5410         frameinfo.desc_addr = NULL;
   5411         frameinfo.desc_size = 0;
   5412     }
   5413     if (!arbitrary_bytes) {
   5414         frameinfo.flags |= buffer->nFlags;
   5415     }
   5416 
   5417 #ifdef _ANDROID_
   5418     if (m_debug_timestamp) {
   5419         if (arbitrary_bytes) {
   5420             DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   5421             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   5422         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   5423             DEBUG_PRINT_LOW("\n Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   5424             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   5425         }
   5426     }
   5427 #endif
   5428 
   5429 #ifdef INPUT_BUFFER_LOG
   5430     if (output_capability == V4L2_PIX_FMT_VP8) {
   5431         struct vp8_ivf_frame_header {
   5432             OMX_U32 framesize;
   5433             OMX_U32 timestamp_lo;
   5434             OMX_U32 timestamp_hi;
   5435         } vp8_frame_header;
   5436         vp8_frame_header.framesize = temp_buffer->buffer_len;
   5437         /* Currently FW doesn't use timestamp values */
   5438         vp8_frame_header.timestamp_lo = 0;
   5439         vp8_frame_header.timestamp_hi = 0;
   5440         if (inputBufferFile1) {
   5441             fwrite((const char *)&vp8_frame_header,
   5442                     sizeof(vp8_frame_header),1,inputBufferFile1);
   5443             fwrite((const char *)temp_buffer->bufferaddr,
   5444                     temp_buffer->buffer_len,1,inputBufferFile1);
   5445         }
   5446     } else {
   5447         if (inputBufferFile1) {
   5448             fwrite((const char *)temp_buffer->bufferaddr,
   5449                     temp_buffer->buffer_len,1,inputBufferFile1);
   5450         }
   5451     }
   5452 #endif
   5453 
   5454     if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   5455         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   5456         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   5457     }
   5458 
   5459     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   5460         DEBUG_PRINT_HIGH("\n Rxd i/p EOS, Notify Driver that EOS has been reached");
   5461         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   5462         h264_scratch.nFilledLen = 0;
   5463         nal_count = 0;
   5464         look_ahead_nal = false;
   5465         frame_count = 0;
   5466         if (m_frame_parser.mutils)
   5467             m_frame_parser.mutils->initialize_frame_checking_environment();
   5468         m_frame_parser.flush();
   5469         h264_last_au_ts = LLONG_MAX;
   5470         h264_last_au_flags = 0;
   5471         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   5472         m_demux_entries = 0;
   5473     }
   5474     struct v4l2_buffer buf;
   5475     struct v4l2_plane plane;
   5476     memset( (void *)&buf, 0, sizeof(buf));
   5477     memset( (void *)&plane, 0, sizeof(plane));
   5478     int rc;
   5479     unsigned long  print_count;
   5480     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   5481         buf.flags = V4L2_BUF_FLAG_EOS;
   5482         DEBUG_PRINT_HIGH("\n  INPUT EOS reached \n") ;
   5483     }
   5484     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5485     buf.index = nPortIndex;
   5486     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5487     buf.memory = V4L2_MEMORY_USERPTR;
   5488     plane.bytesused = temp_buffer->buffer_len;
   5489     plane.length = drv_ctx.ip_buf.buffer_size;
   5490     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   5491         (unsigned long)temp_buffer->offset;
   5492     plane.reserved[0] = temp_buffer->pmem_fd;
   5493     plane.reserved[1] = temp_buffer->offset;
   5494     plane.data_offset = 0;
   5495     buf.m.planes = &plane;
   5496     buf.length = 1;
   5497     if (frameinfo.timestamp >= LLONG_MAX) {
   5498         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   5499     }
   5500     //assumption is that timestamp is in milliseconds
   5501     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   5502     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   5503     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   5504     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   5505 
   5506     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   5507     if (rc) {
   5508         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver\n");
   5509         return OMX_ErrorHardware;
   5510     }
   5511     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   5512         codec_config_flag = false;
   5513     }
   5514     if (!streaming[OUTPUT_PORT]) {
   5515         enum v4l2_buf_type buf_type;
   5516         int ret,r;
   5517 
   5518         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5519         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing\n");
   5520         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   5521         if (!ret) {
   5522             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful \n");
   5523             streaming[OUTPUT_PORT] = true;
   5524         } else {
   5525             DEBUG_PRINT_ERROR(" \n Failed to call streamon on OUTPUT \n");
   5526             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   5527             post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
   5528                     OMX_COMPONENT_GENERATE_EBD);
   5529             return OMX_ErrorBadParameter;
   5530         }
   5531     }
   5532     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
   5533             frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
   5534     time_stamp_dts.insert_timestamp(buffer);
   5535 
   5536     return ret;
   5537 }
   5538 
   5539 /* ======================================================================
   5540    FUNCTION
   5541    omx_vdec::FillThisBuffer
   5542 
   5543    DESCRIPTION
   5544    IL client uses this method to release the frame buffer
   5545    after displaying them.
   5546 
   5547    PARAMETERS
   5548    None.
   5549 
   5550    RETURN VALUE
   5551    true/false
   5552 
   5553    ========================================================================== */
   5554 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   5555         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5556 {
   5557     if (dynamic_buf_mode) {
   5558         private_handle_t *handle = NULL;
   5559         struct VideoDecoderOutputMetaData *meta;
   5560         unsigned int nPortIndex = 0;
   5561 
   5562         if (!buffer || !buffer->pBuffer) {
   5563             DEBUG_PRINT_ERROR("%s: invalid params: %p %p", __FUNCTION__, buffer, buffer->pBuffer);
   5564             return OMX_ErrorBadParameter;
   5565         }
   5566 
   5567         //get the buffer type and fd info
   5568         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   5569         handle = (private_handle_t *)meta->pHandle;
   5570         DEBUG_PRINT_LOW("FTB: buftype: %d bufhndl: %p", meta->eType, meta->pHandle);
   5571 
   5572 
   5573         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   5574         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   5575         drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   5576         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   5577     }
   5578 
   5579 
   5580     if (m_state == OMX_StateInvalid) {
   5581         DEBUG_PRINT_ERROR("FTB in Invalid State\n");
   5582         return OMX_ErrorInvalidState;
   5583     }
   5584 
   5585     if (!m_out_bEnabled) {
   5586         DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
   5587         return OMX_ErrorIncorrectStateOperation;
   5588     }
   5589 
   5590     if (buffer == NULL ||
   5591             ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
   5592         return OMX_ErrorBadParameter;
   5593     }
   5594 
   5595     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   5596         DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %lu", buffer->nOutputPortIndex);
   5597         return OMX_ErrorBadPortIndex;
   5598     }
   5599 
   5600     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   5601     post_event((unsigned) hComp, (unsigned)buffer, m_fill_output_msg);
   5602     return OMX_ErrorNone;
   5603 }
   5604 /* ======================================================================
   5605    FUNCTION
   5606    omx_vdec::fill_this_buffer_proxy
   5607 
   5608    DESCRIPTION
   5609    IL client uses this method to release the frame buffer
   5610    after displaying them.
   5611 
   5612    PARAMETERS
   5613    None.
   5614 
   5615    RETURN VALUE
   5616    true/false
   5617 
   5618    ========================================================================== */
   5619 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   5620         OMX_IN OMX_HANDLETYPE        hComp,
   5621         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   5622 {
   5623     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   5624     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   5625     unsigned nPortIndex = 0;
   5626     struct vdec_fillbuffer_cmd fillbuffer;
   5627     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   5628     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   5629 
   5630     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   5631 
   5632     if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount)
   5633         return OMX_ErrorBadParameter;
   5634 
   5635     DEBUG_PRINT_LOW("\n FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   5636             bufferAdd, bufferAdd->pBuffer);
   5637     /*Return back the output buffer to client*/
   5638     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
   5639         DEBUG_PRINT_LOW("\n Output Buffers return flush/disable condition");
   5640         buffer->nFilledLen = 0;
   5641         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   5642         return OMX_ErrorNone;
   5643     }
   5644     if (dynamic_buf_mode) {
   5645         //map the buffer handle based on the size set on output port definition.
   5646         if (!secure_mode) {
   5647             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   5648                 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
   5649                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5650                 drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   5651         }
   5652         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   5653         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
   5654         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
   5655         buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
   5656                    drv_ctx.ptr_outputbuffer[nPortIndex].offset);
   5657     }
   5658     pending_output_buffers++;
   5659     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   5660     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   5661     if (ptr_respbuffer) {
   5662         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   5663     }
   5664 
   5665     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   5666         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   5667         buffer->nFilledLen = 0;
   5668         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   5669         pending_output_buffers--;
   5670         return OMX_ErrorBadParameter;
   5671     }
   5672 
   5673     int rc = 0;
   5674     struct v4l2_buffer buf;
   5675     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5676     memset( (void *)&buf, 0, sizeof(buf));
   5677     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   5678     int extra_idx = 0;
   5679 
   5680     buf.index = nPortIndex;
   5681     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5682     buf.memory = V4L2_MEMORY_USERPTR;
   5683     plane[0].bytesused = buffer->nFilledLen;
   5684     plane[0].length = drv_ctx.op_buf.buffer_size;
   5685     plane[0].m.userptr =
   5686         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   5687         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   5688     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   5689     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   5690     plane[0].data_offset = 0;
   5691     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   5692     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   5693         plane[extra_idx].bytesused = 0;
   5694         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   5695         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   5696 #ifdef USE_ION
   5697         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   5698 #endif
   5699         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   5700         plane[extra_idx].data_offset = 0;
   5701     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   5702         DEBUG_PRINT_ERROR("Extradata index higher than expected: %d\n", extra_idx);
   5703         return OMX_ErrorBadParameter;
   5704     }
   5705     buf.m.planes = plane;
   5706     buf.length = drv_ctx.num_planes;
   5707     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d\n",
   5708              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
   5709 
   5710     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   5711     if (rc) {
   5712         /*TODO: How to handle this case */
   5713         DEBUG_PRINT_ERROR("Failed to qbuf to driver");
   5714     }
   5715     return OMX_ErrorNone;
   5716 }
   5717 
   5718 /* ======================================================================
   5719    FUNCTION
   5720    omx_vdec::SetCallbacks
   5721 
   5722    DESCRIPTION
   5723    Set the callbacks.
   5724 
   5725    PARAMETERS
   5726    None.
   5727 
   5728    RETURN VALUE
   5729    OMX Error None if everything successful.
   5730 
   5731    ========================================================================== */
   5732 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   5733         OMX_IN OMX_CALLBACKTYPE* callbacks,
   5734         OMX_IN OMX_PTR             appData)
   5735 {
   5736 
   5737     m_cb       = *callbacks;
   5738     DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   5739             m_cb.EventHandler,m_cb.FillBufferDone);
   5740     m_app_data =    appData;
   5741     return OMX_ErrorNotImplemented;
   5742 }
   5743 
   5744 /* ======================================================================
   5745    FUNCTION
   5746    omx_vdec::ComponentDeInit
   5747 
   5748    DESCRIPTION
   5749    Destroys the component and release memory allocated to the heap.
   5750 
   5751    PARAMETERS
   5752    <TBD>.
   5753 
   5754    RETURN VALUE
   5755    OMX Error None if everything successful.
   5756 
   5757    ========================================================================== */
   5758 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   5759 {
   5760 #ifdef _ANDROID_
   5761     if (iDivXDrmDecrypt) {
   5762         delete iDivXDrmDecrypt;
   5763         iDivXDrmDecrypt=NULL;
   5764     }
   5765 #endif //_ANDROID_
   5766 
   5767     unsigned i = 0;
   5768     if (OMX_StateLoaded != m_state) {
   5769         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
   5770                 m_state);
   5771         DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
   5772     } else {
   5773         DEBUG_PRINT_HIGH("\n Playback Ended - PASSED");
   5774     }
   5775 
   5776     /*Check if the output buffers have to be cleaned up*/
   5777     if (m_out_mem_ptr) {
   5778         DEBUG_PRINT_LOW("Freeing the Output Memory\n");
   5779         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   5780             free_output_buffer (&m_out_mem_ptr[i]);
   5781         }
   5782 #ifdef _ANDROID_ICS_
   5783         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   5784 #endif
   5785     }
   5786 
   5787     /*Check if the input buffers have to be cleaned up*/
   5788     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   5789         DEBUG_PRINT_LOW("Freeing the Input Memory\n");
   5790         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   5791             if (m_inp_mem_ptr)
   5792                 free_input_buffer (i,&m_inp_mem_ptr[i]);
   5793             else
   5794                 free_input_buffer (i,NULL);
   5795         }
   5796     }
   5797     free_input_buffer_header();
   5798     free_output_buffer_header();
   5799     if (h264_scratch.pBuffer) {
   5800         free(h264_scratch.pBuffer);
   5801         h264_scratch.pBuffer = NULL;
   5802     }
   5803 
   5804     if (h264_parser) {
   5805         delete h264_parser;
   5806         h264_parser = NULL;
   5807     }
   5808 
   5809     if (m_frame_parser.mutils) {
   5810         DEBUG_PRINT_LOW("\n Free utils parser");
   5811         delete (m_frame_parser.mutils);
   5812         m_frame_parser.mutils = NULL;
   5813     }
   5814 
   5815     if (m_platform_list) {
   5816         free(m_platform_list);
   5817         m_platform_list = NULL;
   5818     }
   5819     if (m_vendor_config.pData) {
   5820         free(m_vendor_config.pData);
   5821         m_vendor_config.pData = NULL;
   5822     }
   5823 
   5824     // Reset counters in mesg queues
   5825     m_ftb_q.m_size=0;
   5826     m_cmd_q.m_size=0;
   5827     m_etb_q.m_size=0;
   5828     m_ftb_q.m_read = m_ftb_q.m_write =0;
   5829     m_cmd_q.m_read = m_cmd_q.m_write =0;
   5830     m_etb_q.m_read = m_etb_q.m_write =0;
   5831 #ifdef _ANDROID_
   5832     if (m_debug_timestamp) {
   5833         m_timestamp_list.reset_ts_list();
   5834     }
   5835 #endif
   5836 
   5837     DEBUG_PRINT_LOW("\n Calling VDEC_IOCTL_STOP_NEXT_MSG");
   5838     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   5839     // NULL);
   5840     DEBUG_PRINT_HIGH("\n Close the driver instance");
   5841 
   5842 #ifdef INPUT_BUFFER_LOG
   5843     if (inputBufferFile1)
   5844         fclose (inputBufferFile1);
   5845 #endif
   5846 #ifdef OUTPUT_BUFFER_LOG
   5847     if (outputBufferFile1)
   5848         fclose (outputBufferFile1);
   5849 #endif
   5850 #ifdef OUTPUT_EXTRADATA_LOG
   5851     if (outputExtradataFile)
   5852         fclose (outputExtradataFile);
   5853 #endif
   5854     DEBUG_PRINT_HIGH("\n omx_vdec::component_deinit() complete");
   5855     return OMX_ErrorNone;
   5856 }
   5857 
   5858 /* ======================================================================
   5859    FUNCTION
   5860    omx_vdec::UseEGLImage
   5861 
   5862    DESCRIPTION
   5863    OMX Use EGL Image method implementation <TBD>.
   5864 
   5865    PARAMETERS
   5866    <TBD>.
   5867 
   5868    RETURN VALUE
   5869    Not Implemented error.
   5870 
   5871    ========================================================================== */
   5872 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
   5873         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5874         OMX_IN OMX_U32                        port,
   5875         OMX_IN OMX_PTR                     appData,
   5876         OMX_IN void*                      eglImage)
   5877 {
   5878     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   5879     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   5880     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   5881 
   5882 #ifdef USE_EGL_IMAGE_GPU
   5883     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   5884     EGLint fd = -1, offset = 0,pmemPtr = 0;
   5885 #else
   5886     int fd = -1, offset = 0;
   5887 #endif
   5888     DEBUG_PRINT_HIGH("\nuse EGL image support for decoder");
   5889     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   5890         DEBUG_PRINT_ERROR("\n ");
   5891     }
   5892 #ifdef USE_EGL_IMAGE_GPU
   5893     if (m_display_id == NULL) {
   5894         DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
   5895         return OMX_ErrorInsufficientResources;
   5896     }
   5897     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   5898         eglGetProcAddress("eglQueryImageKHR");
   5899     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
   5900     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
   5901     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
   5902 #else //with OMX test app
   5903     struct temp_egl {
   5904         int pmem_fd;
   5905         int offset;
   5906     };
   5907     struct temp_egl *temp_egl_id = NULL;
   5908     void * pmemPtr = (void *) eglImage;
   5909     temp_egl_id = (struct temp_egl *)eglImage;
   5910     if (temp_egl_id != NULL) {
   5911         fd = temp_egl_id->pmem_fd;
   5912         offset = temp_egl_id->offset;
   5913     }
   5914 #endif
   5915     if (fd < 0) {
   5916         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d  \n",fd);
   5917         return OMX_ErrorInsufficientResources;
   5918     }
   5919     pmem_info.pmem_fd = (OMX_U32) fd;
   5920     pmem_info.offset = (OMX_U32) offset;
   5921     pmem_entry.entry = (void *) &pmem_info;
   5922     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   5923     pmem_list.entryList = &pmem_entry;
   5924     pmem_list.nEntries = 1;
   5925     ouput_egl_buffers = true;
   5926     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   5927                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   5928                 (OMX_U8 *)pmemPtr)) {
   5929         DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
   5930         return OMX_ErrorInsufficientResources;
   5931     }
   5932     return OMX_ErrorNone;
   5933 }
   5934 
   5935 /* ======================================================================
   5936    FUNCTION
   5937    omx_vdec::ComponentRoleEnum
   5938 
   5939    DESCRIPTION
   5940    OMX Component Role Enum method implementation.
   5941 
   5942    PARAMETERS
   5943    <TBD>.
   5944 
   5945    RETURN VALUE
   5946    OMX Error None if everything is successful.
   5947    ========================================================================== */
   5948 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   5949         OMX_OUT OMX_U8*        role,
   5950         OMX_IN OMX_U32        index)
   5951 {
   5952     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5953 
   5954     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   5955         if ((0 == index) && role) {
   5956             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   5957             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   5958         } else {
   5959             eRet = OMX_ErrorNoMore;
   5960         }
   5961     }
   5962     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   5963         if ((0 == index) && role) {
   5964             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   5965             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   5966         } else {
   5967             eRet = OMX_ErrorNoMore;
   5968         }
   5969     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   5970         if ((0 == index) && role) {
   5971             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   5972             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   5973         } else {
   5974             DEBUG_PRINT_LOW("\n No more roles \n");
   5975             eRet = OMX_ErrorNoMore;
   5976         }
   5977     }
   5978 
   5979     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   5980             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
   5981         )
   5982 
   5983     {
   5984         if ((0 == index) && role) {
   5985             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   5986             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   5987         } else {
   5988             DEBUG_PRINT_LOW("\n No more roles \n");
   5989             eRet = OMX_ErrorNoMore;
   5990         }
   5991     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   5992         if ((0 == index) && role) {
   5993             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   5994             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   5995         } else {
   5996             DEBUG_PRINT_LOW("\n No more roles \n");
   5997             eRet = OMX_ErrorNoMore;
   5998         }
   5999     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   6000             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   6001           ) {
   6002         if ((0 == index) && role) {
   6003             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   6004             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   6005         } else {
   6006             DEBUG_PRINT_LOW("\n No more roles \n");
   6007             eRet = OMX_ErrorNoMore;
   6008         }
   6009     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   6010         if ((0 == index) && role) {
   6011             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   6012             DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
   6013         } else {
   6014             DEBUG_PRINT_LOW("\n No more roles \n");
   6015             eRet = OMX_ErrorNoMore;
   6016         }
   6017     } else {
   6018         DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component\n");
   6019         eRet = OMX_ErrorInvalidComponentName;
   6020     }
   6021     return eRet;
   6022 }
   6023 
   6024 
   6025 
   6026 
   6027 /* ======================================================================
   6028    FUNCTION
   6029    omx_vdec::AllocateDone
   6030 
   6031    DESCRIPTION
   6032    Checks if entire buffer pool is allocated by IL Client or not.
   6033    Need this to move to IDLE state.
   6034 
   6035    PARAMETERS
   6036    None.
   6037 
   6038    RETURN VALUE
   6039    true/false.
   6040 
   6041    ========================================================================== */
   6042 bool omx_vdec::allocate_done(void)
   6043 {
   6044     bool bRet = false;
   6045     bool bRet_In = false;
   6046     bool bRet_Out = false;
   6047 
   6048     bRet_In = allocate_input_done();
   6049     bRet_Out = allocate_output_done();
   6050 
   6051     if (bRet_In && bRet_Out) {
   6052         bRet = true;
   6053     }
   6054 
   6055     return bRet;
   6056 }
   6057 /* ======================================================================
   6058    FUNCTION
   6059    omx_vdec::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_vdec::allocate_input_done(void)
   6072 {
   6073     bool bRet = false;
   6074     unsigned i=0;
   6075 
   6076     if (m_inp_mem_ptr == NULL) {
   6077         return bRet;
   6078     }
   6079     if (m_inp_mem_ptr ) {
   6080         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   6081             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6082                 break;
   6083             }
   6084         }
   6085     }
   6086     if (i == drv_ctx.ip_buf.actualcount) {
   6087         bRet = true;
   6088         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   6089     }
   6090     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   6091         m_inp_bPopulated = OMX_TRUE;
   6092     }
   6093     return bRet;
   6094 }
   6095 /* ======================================================================
   6096    FUNCTION
   6097    omx_vdec::AllocateOutputDone
   6098 
   6099    DESCRIPTION
   6100    Checks if entire O/P buffer pool is allocated by IL Client or not.
   6101 
   6102    PARAMETERS
   6103    None.
   6104 
   6105    RETURN VALUE
   6106    true/false.
   6107 
   6108    ========================================================================== */
   6109 bool omx_vdec::allocate_output_done(void)
   6110 {
   6111     bool bRet = false;
   6112     unsigned j=0;
   6113 
   6114     if (m_out_mem_ptr == NULL) {
   6115         return bRet;
   6116     }
   6117 
   6118     if (m_out_mem_ptr) {
   6119         for (; j < drv_ctx.op_buf.actualcount; j++) {
   6120             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   6121                 break;
   6122             }
   6123         }
   6124     }
   6125 
   6126     if (j == drv_ctx.op_buf.actualcount) {
   6127         bRet = true;
   6128         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   6129         if (m_out_bEnabled)
   6130             m_out_bPopulated = OMX_TRUE;
   6131     }
   6132 
   6133     return bRet;
   6134 }
   6135 
   6136 /* ======================================================================
   6137    FUNCTION
   6138    omx_vdec::ReleaseDone
   6139 
   6140    DESCRIPTION
   6141    Checks if IL client has released all the buffers.
   6142 
   6143    PARAMETERS
   6144    None.
   6145 
   6146    RETURN VALUE
   6147    true/false
   6148 
   6149    ========================================================================== */
   6150 bool omx_vdec::release_done(void)
   6151 {
   6152     bool bRet = false;
   6153 
   6154     if (release_input_done()) {
   6155         if (release_output_done()) {
   6156             bRet = true;
   6157         }
   6158     }
   6159     return bRet;
   6160 }
   6161 
   6162 
   6163 /* ======================================================================
   6164    FUNCTION
   6165    omx_vdec::ReleaseOutputDone
   6166 
   6167    DESCRIPTION
   6168    Checks if IL client has released all the buffers.
   6169 
   6170    PARAMETERS
   6171    None.
   6172 
   6173    RETURN VALUE
   6174    true/false
   6175 
   6176    ========================================================================== */
   6177 bool omx_vdec::release_output_done(void)
   6178 {
   6179     bool bRet = false;
   6180     unsigned i=0,j=0;
   6181 
   6182     DEBUG_PRINT_LOW("\n Value of m_out_mem_ptr %p",m_inp_mem_ptr);
   6183     if (m_out_mem_ptr) {
   6184         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   6185             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   6186                 break;
   6187             }
   6188         }
   6189         if (j == drv_ctx.op_buf.actualcount) {
   6190             m_out_bm_count = 0;
   6191             bRet = true;
   6192         }
   6193     } else {
   6194         m_out_bm_count = 0;
   6195         bRet = true;
   6196     }
   6197     return bRet;
   6198 }
   6199 /* ======================================================================
   6200    FUNCTION
   6201    omx_vdec::ReleaseInputDone
   6202 
   6203    DESCRIPTION
   6204    Checks if IL client has released all the buffers.
   6205 
   6206    PARAMETERS
   6207    None.
   6208 
   6209    RETURN VALUE
   6210    true/false
   6211 
   6212    ========================================================================== */
   6213 bool omx_vdec::release_input_done(void)
   6214 {
   6215     bool bRet = false;
   6216     unsigned i=0,j=0;
   6217 
   6218     DEBUG_PRINT_LOW("\n Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   6219     if (m_inp_mem_ptr) {
   6220         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   6221             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   6222                 break;
   6223             }
   6224         }
   6225         if (j==drv_ctx.ip_buf.actualcount) {
   6226             bRet = true;
   6227         }
   6228     } else {
   6229         bRet = true;
   6230     }
   6231     return bRet;
   6232 }
   6233 
   6234 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   6235         OMX_BUFFERHEADERTYPE * buffer)
   6236 {
   6237     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   6238     if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
   6239         DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
   6240         return OMX_ErrorBadParameter;
   6241     } else if (output_flush_progress) {
   6242         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   6243         buffer->nFilledLen = 0;
   6244         buffer->nTimeStamp = 0;
   6245         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   6246         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   6247         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   6248     }
   6249 
   6250     if (m_debug_extradata) {
   6251         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   6252             DEBUG_PRINT_HIGH("\n");
   6253             DEBUG_PRINT_HIGH("***************************************************\n");
   6254             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
   6255             DEBUG_PRINT_HIGH("***************************************************\n");
   6256         }
   6257 
   6258         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   6259             DEBUG_PRINT_HIGH("\n");
   6260             DEBUG_PRINT_HIGH("***************************************************\n");
   6261             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
   6262             DEBUG_PRINT_HIGH("***************************************************\n");
   6263         }
   6264     }
   6265 
   6266 
   6267     DEBUG_PRINT_LOW("\n fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   6268             buffer, buffer->pBuffer);
   6269     pending_output_buffers --;
   6270 
   6271     if (dynamic_buf_mode && !secure_mode) {
   6272         unsigned int nPortIndex = 0;
   6273          nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   6274         munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
   6275                         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
   6276     }
   6277 
   6278     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   6279         DEBUG_PRINT_HIGH("\n Output EOS has been reached");
   6280         if (!output_flush_progress)
   6281             post_event((unsigned)NULL, (unsigned)NULL,
   6282                     OMX_COMPONENT_GENERATE_EOS_DONE);
   6283 
   6284         if (psource_frame) {
   6285             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   6286             psource_frame = NULL;
   6287         }
   6288         if (pdest_frame) {
   6289             pdest_frame->nFilledLen = 0;
   6290             m_input_free_q.insert_entry((unsigned) pdest_frame,(unsigned)NULL,
   6291                     (unsigned)NULL);
   6292             pdest_frame = NULL;
   6293         }
   6294     }
   6295 
   6296     DEBUG_PRINT_LOW("\n In fill Buffer done call address %p ",buffer);
   6297 #ifdef OUTPUT_BUFFER_LOG
   6298     if (outputBufferFile1 && buffer->nFilledLen) {
   6299         int buf_index = buffer - m_out_mem_ptr;
   6300         int stride = drv_ctx.video_resolution.stride;
   6301         int scanlines = drv_ctx.video_resolution.scan_lines;
   6302         char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   6303         unsigned i;
   6304         int bytes_written = 0;
   6305         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   6306             bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
   6307             temp += stride;
   6308         }
   6309         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   6310         int stride_c = stride;
   6311         for (i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   6312             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, outputBufferFile1);
   6313             temp += stride_c;
   6314         }
   6315     }
   6316 #endif
   6317 
   6318     /* For use buffer we need to copy the data */
   6319     if (!output_flush_progress) {
   6320         /* This is the error check for non-recoverable errros */
   6321         bool is_duplicate_ts_valid = true;
   6322         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   6323 
   6324         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   6325                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   6326                 output_capability == V4L2_PIX_FMT_DIVX ||
   6327                 output_capability == V4L2_PIX_FMT_DIVX_311)
   6328             is_duplicate_ts_valid = false;
   6329 
   6330         if (output_capability == V4L2_PIX_FMT_H264 && is_interlaced) {
   6331             bool mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
   6332             if (mbaff) {
   6333                 is_interlaced = false;
   6334             }
   6335         }
   6336 
   6337         if (buffer->nFilledLen > 0) {
   6338             time_stamp_dts.get_next_timestamp(buffer,
   6339                     is_interlaced && is_duplicate_ts_valid);
   6340             if (m_debug_timestamp) {
   6341                 {
   6342                     OMX_TICKS expected_ts = 0;
   6343                     m_timestamp_list.pop_min_ts(expected_ts);
   6344                     if (is_interlaced && is_duplicate_ts_valid) {
   6345                         m_timestamp_list.pop_min_ts(expected_ts);
   6346                     }
   6347                     DEBUG_PRINT_LOW("\n Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   6348                             buffer->nTimeStamp, expected_ts);
   6349 
   6350                     if (buffer->nTimeStamp != expected_ts) {
   6351                         DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
   6352                     }
   6353                 }
   6354             }
   6355         } else {
   6356             m_inp_err_count++;
   6357             time_stamp_dts.remove_time_stamp(
   6358                     buffer->nTimeStamp,
   6359                     is_interlaced && is_duplicate_ts_valid);
   6360         }
   6361 
   6362 
   6363     }
   6364     if (m_cb.FillBufferDone) {
   6365         if (buffer->nFilledLen > 0) {
   6366             handle_extradata(buffer);
   6367             if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   6368                 set_frame_rate(buffer->nTimeStamp);
   6369             else if (arbitrary_bytes)
   6370                 adjust_timestamp(buffer->nTimeStamp);
   6371             if (perf_flag) {
   6372                 if (!proc_frms) {
   6373                     dec_time.stop();
   6374                     latency = dec_time.processing_time_us() - latency;
   6375                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   6376                     dec_time.start();
   6377                     fps_metrics.start();
   6378                 }
   6379                 proc_frms++;
   6380                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   6381                     OMX_U64 proc_time = 0;
   6382                     fps_metrics.stop();
   6383                     proc_time = fps_metrics.processing_time_us();
   6384                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
   6385                             proc_frms, (float)proc_time / 1e6,
   6386                             (float)(1e6 * proc_frms) / proc_time);
   6387                     proc_frms = 0;
   6388                 }
   6389             }
   6390 
   6391 #ifdef OUTPUT_EXTRADATA_LOG
   6392             if (outputExtradataFile) {
   6393 
   6394                 OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   6395                 p_extra = (OMX_OTHER_EXTRADATATYPE *)
   6396                     ((unsigned)(buffer->pBuffer + buffer->nOffset +
   6397                         buffer->nFilledLen + 3)&(~3));
   6398                 while (p_extra &&
   6399                         (OMX_U8*)p_extra < (buffer->pBuffer + buffer->nAllocLen) ) {
   6400                     DEBUG_PRINT_LOW("\nWRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
   6401                     fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   6402                     if (p_extra->eType == OMX_ExtraDataNone) {
   6403                         break;
   6404                     }
   6405                     p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   6406                 }
   6407             }
   6408 #endif
   6409         }
   6410         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   6411             prev_ts = LLONG_MAX;
   6412             rst_prev_ts = true;
   6413         }
   6414 
   6415         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   6416             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   6417              buffer->pPlatformPrivate)->entryList->entry;
   6418         DEBUG_PRINT_LOW("\n Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   6419         OMX_BUFFERHEADERTYPE *il_buffer;
   6420         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   6421         if (il_buffer)
   6422             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   6423         else {
   6424             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   6425             return OMX_ErrorBadParameter;
   6426         }
   6427         DEBUG_PRINT_LOW("\n After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   6428     } else {
   6429         return OMX_ErrorBadParameter;
   6430     }
   6431 
   6432     if (mInSmoothstreamingMode) {
   6433         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   6434         BufferDim_t dim;
   6435         dim.sliceWidth = drv_ctx.video_resolution.frame_width;
   6436         dim.sliceHeight = drv_ctx.video_resolution.frame_height;
   6437         DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   6438                 dim.sliceWidth, dim.sliceHeight);
   6439         private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
   6440         if (private_handle) {
   6441             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   6442         }
   6443   }
   6444 
   6445     return OMX_ErrorNone;
   6446 }
   6447 
   6448 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   6449         OMX_BUFFERHEADERTYPE* buffer)
   6450 {
   6451 
   6452     if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
   6453         DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
   6454         return OMX_ErrorBadParameter;
   6455     }
   6456 
   6457     DEBUG_PRINT_LOW("\n empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   6458             buffer, buffer->pBuffer);
   6459     pending_input_buffers--;
   6460 
   6461     if (arbitrary_bytes) {
   6462         if (pdest_frame == NULL && input_flush_progress == false) {
   6463             DEBUG_PRINT_LOW("\n Push input from buffer done address of Buffer %p",buffer);
   6464             pdest_frame = buffer;
   6465             buffer->nFilledLen = 0;
   6466             buffer->nTimeStamp = LLONG_MAX;
   6467             push_input_buffer (hComp);
   6468         } else {
   6469             DEBUG_PRINT_LOW("\n Push buffer into freeq address of Buffer %p",buffer);
   6470             buffer->nFilledLen = 0;
   6471             if (!m_input_free_q.insert_entry((unsigned)buffer,
   6472                         (unsigned)NULL, (unsigned)NULL)) {
   6473                 DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
   6474             }
   6475         }
   6476     } else if (m_cb.EmptyBufferDone) {
   6477         buffer->nFilledLen = 0;
   6478         if (input_use_buffer == true) {
   6479             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   6480         }
   6481         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   6482     }
   6483     return OMX_ErrorNone;
   6484 }
   6485 
   6486 int omx_vdec::async_message_process (void *context, void* message)
   6487 {
   6488     omx_vdec* omx = NULL;
   6489     struct vdec_msginfo *vdec_msg = NULL;
   6490     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   6491     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   6492     struct vdec_output_frameinfo *output_respbuf = NULL;
   6493     int rc=1;
   6494     if (context == NULL || message == NULL) {
   6495         DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
   6496         return -1;
   6497     }
   6498     vdec_msg = (struct vdec_msginfo *)message;
   6499 
   6500     omx = reinterpret_cast<omx_vdec*>(context);
   6501 
   6502     switch (vdec_msg->msgcode) {
   6503 
   6504         case VDEC_MSG_EVT_HW_ERROR:
   6505             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6506                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   6507             break;
   6508 
   6509         case VDEC_MSG_RESP_START_DONE:
   6510             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6511                     OMX_COMPONENT_GENERATE_START_DONE);
   6512             break;
   6513 
   6514         case VDEC_MSG_RESP_STOP_DONE:
   6515             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6516                     OMX_COMPONENT_GENERATE_STOP_DONE);
   6517             break;
   6518 
   6519         case VDEC_MSG_RESP_RESUME_DONE:
   6520             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6521                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   6522             break;
   6523 
   6524         case VDEC_MSG_RESP_PAUSE_DONE:
   6525             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6526                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   6527             break;
   6528 
   6529         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   6530             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6531                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   6532             break;
   6533         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   6534             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   6535                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   6536             break;
   6537         case VDEC_MSG_RESP_INPUT_FLUSHED:
   6538         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   6539 
   6540             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   6541                vdec_msg->msgdata.input_frame_clientdata; */
   6542 
   6543             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   6544             omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
   6545             if (omxhdr == NULL ||
   6546                     ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
   6547                 omxhdr = NULL;
   6548                 vdec_msg->status_code = VDEC_S_EFATAL;
   6549             }
   6550             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   6551                 DEBUG_PRINT_HIGH("Unsupported input");
   6552                 omx->omx_report_error ();
   6553             }
   6554             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   6555                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   6556             }
   6557             omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
   6558                     OMX_COMPONENT_GENERATE_EBD);
   6559             break;
   6560         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   6561             int64_t *timestamp;
   6562             timestamp = (int64_t *) malloc(sizeof(int64_t));
   6563             if (timestamp) {
   6564                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   6565                 omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
   6566                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   6567                 DEBUG_PRINT_HIGH("\nField dropped time stamp is %lld",
   6568                         vdec_msg->msgdata.output_frame.time_stamp);
   6569             }
   6570             break;
   6571         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   6572         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   6573 
   6574             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   6575             omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
   6576             DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
   6577                     omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
   6578                     vdec_msg->msgdata.output_frame.pic_type);
   6579 
   6580             if (omxhdr && omxhdr->pOutputPortPrivate &&
   6581                     ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
   6582                     (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   6583                       - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
   6584                 if (omx->dynamic_buf_mode && vdec_msg->msgdata.output_frame.len) {
   6585                     vdec_msg->msgdata.output_frame.len = omxhdr->nAllocLen;
   6586                 }
   6587                 if ( vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   6588                     omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   6589                     omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   6590                     omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   6591                     omxhdr->nFlags = 0;
   6592 
   6593                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS) {
   6594                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   6595                         //rc = -1;
   6596                     }
   6597                     if (omxhdr->nFilledLen) {
   6598                         omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   6599                     }
   6600                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   6601                         omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   6602                     } else {
   6603                         omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   6604                     }
   6605                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   6606                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   6607                     }
   6608                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   6609                         omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   6610                     }
   6611 
   6612                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   6613                          DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   6614                                     omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   6615                     } else {
   6616                         DEBUG_PRINT_LOW("F_B_D: REFERENCE RELEASED BY F/W: %d",
   6617                                     omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   6618                     }
   6619 
   6620                     if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
   6621                         omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd, omxhdr->nOffset);
   6622                     }
   6623                     if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   6624                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   6625                             !(v4l2_buf_ptr->flags & V4L2_BUF_FLAG_EOS)) {
   6626                         omx->post_event ((unsigned)NULL,(unsigned int)omxhdr,
   6627                                 OMX_COMPONENT_GENERATE_FTB);
   6628                         break;
   6629                     }
   6630                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   6631                         omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   6632                     }
   6633                     vdec_msg->msgdata.output_frame.bufferaddr =
   6634                         omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   6635                     int format_notably_changed = 0;
   6636                     if (omxhdr->nFilledLen &&
   6637                             (omxhdr->nFilledLen != omx->prev_n_filled_len)) {
   6638                         if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
   6639                                 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
   6640                             DEBUG_PRINT_HIGH("\n Height/Width information has changed\n");
   6641                             omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
   6642                             omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
   6643                             format_notably_changed = 1;
   6644                         }
   6645                     }
   6646                     if (omxhdr->nFilledLen && (((unsigned)omx->rectangle.nLeft !=
   6647                                     vdec_msg->msgdata.output_frame.framesize.left)
   6648                                 || ((unsigned)omx->rectangle.nTop != vdec_msg->msgdata.output_frame.framesize.top)
   6649                                 || (omx->rectangle.nWidth != vdec_msg->msgdata.output_frame.framesize.right)
   6650                                 || (omx->rectangle.nHeight != vdec_msg->msgdata.output_frame.framesize.bottom))) {
   6651                         if ((vdec_msg->msgdata.output_frame.framesize.bottom != omx->drv_ctx.video_resolution.frame_height) ||
   6652                                 (vdec_msg->msgdata.output_frame.framesize.right != omx->drv_ctx.video_resolution.frame_width)) {
   6653                             omx->drv_ctx.video_resolution.frame_height = vdec_msg->msgdata.output_frame.framesize.bottom;
   6654                             omx->drv_ctx.video_resolution.frame_width = vdec_msg->msgdata.output_frame.framesize.right;
   6655                             DEBUG_PRINT_HIGH("\n Height/Width information has changed. W: %d --> %d, H: %d --> %d\n",
   6656                                     omx->drv_ctx.video_resolution.frame_width, vdec_msg->msgdata.output_frame.framesize.right,
   6657                                     omx->drv_ctx.video_resolution.frame_height, vdec_msg->msgdata.output_frame.framesize.bottom);
   6658                         }
   6659                         DEBUG_PRINT_HIGH("\n Crop information changed. W: %d --> %d, H: %d -> %d\n",
   6660                                 omx->rectangle.nWidth, vdec_msg->msgdata.output_frame.framesize.right,
   6661                                 omx->rectangle.nHeight, vdec_msg->msgdata.output_frame.framesize.bottom);
   6662                         omx->rectangle.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
   6663                         omx->rectangle.nTop = vdec_msg->msgdata.output_frame.framesize.top;
   6664                         omx->rectangle.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
   6665                         omx->rectangle.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
   6666                         format_notably_changed = 1;
   6667                     }
   6668                     if (format_notably_changed) {
   6669                         if (omx->is_video_session_supported()) {
   6670                             omx->post_event (NULL, vdec_msg->status_code,
   6671                                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   6672                         } else {
   6673                             if (!omx->client_buffers.update_buffer_req()) {
   6674                                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   6675                             }
   6676                             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexConfigCommonOutputCrop,
   6677                                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   6678                         }
   6679                     }
   6680                     if (omxhdr->nFilledLen)
   6681                         omx->prev_n_filled_len = omxhdr->nFilledLen;
   6682 
   6683                     output_respbuf = (struct vdec_output_frameinfo *)\
   6684                              omxhdr->pOutputPortPrivate;
   6685                     output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   6686                     output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   6687                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   6688                         output_respbuf->pic_type = PICTURE_TYPE_I;
   6689                     }
   6690                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   6691                         output_respbuf->pic_type = PICTURE_TYPE_P;
   6692                     }
   6693                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   6694                         output_respbuf->pic_type = PICTURE_TYPE_B;
   6695                     }
   6696 
   6697                     if (omx->output_use_buffer)
   6698                         memcpy ( omxhdr->pBuffer, (void *)
   6699                                 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   6700                                  (unsigned long)vdec_msg->msgdata.output_frame.offset),
   6701                                 vdec_msg->msgdata.output_frame.len);
   6702                 } else
   6703                     omxhdr->nFilledLen = 0;
   6704                 omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
   6705                         OMX_COMPONENT_GENERATE_FBD);
   6706             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
   6707                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   6708                         OMX_COMPONENT_GENERATE_EOS_DONE);
   6709             else
   6710                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   6711                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   6712             break;
   6713         case VDEC_MSG_EVT_CONFIG_CHANGED:
   6714             DEBUG_PRINT_HIGH("\n Port settings changed");
   6715             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   6716                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   6717             break;
   6718         default:
   6719             break;
   6720     }
   6721     return rc;
   6722 }
   6723 
   6724 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   6725         OMX_HANDLETYPE hComp,
   6726         OMX_BUFFERHEADERTYPE *buffer
   6727         )
   6728 {
   6729     unsigned address,p2,id;
   6730     DEBUG_PRINT_LOW("\n Empty this arbitrary");
   6731 
   6732     if (buffer == NULL) {
   6733         return OMX_ErrorBadParameter;
   6734     }
   6735     DEBUG_PRINT_LOW("\n ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   6736     DEBUG_PRINT_LOW("\n ETBProxyArb: nFilledLen %lu, flags %lu, timestamp %lld",
   6737             buffer->nFilledLen, buffer->nFlags, buffer->nTimeStamp);
   6738 
   6739     /* return zero length and not an EOS buffer */
   6740     /* return buffer if input flush in progress */
   6741     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   6742                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   6743         DEBUG_PRINT_HIGH("\n return zero legth buffer or flush in progress");
   6744         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   6745         return OMX_ErrorNone;
   6746     }
   6747 
   6748     if (psource_frame == NULL) {
   6749         DEBUG_PRINT_LOW("\n Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   6750         psource_frame = buffer;
   6751         DEBUG_PRINT_LOW("\n Try to Push One Input Buffer ");
   6752         push_input_buffer (hComp);
   6753     } else {
   6754         DEBUG_PRINT_LOW("\n Push the source buffer into pendingq %p",buffer);
   6755         if (!m_input_pending_q.insert_entry((unsigned)buffer, (unsigned)NULL,
   6756                     (unsigned)NULL)) {
   6757             return OMX_ErrorBadParameter;
   6758         }
   6759     }
   6760 
   6761 
   6762     return OMX_ErrorNone;
   6763 }
   6764 
   6765 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   6766 {
   6767     unsigned address,p2,id;
   6768     OMX_ERRORTYPE ret = OMX_ErrorNone;
   6769 
   6770     if (pdest_frame == NULL || psource_frame == NULL) {
   6771         /*Check if we have a destination buffer*/
   6772         if (pdest_frame == NULL) {
   6773             DEBUG_PRINT_LOW("\n Get a Destination buffer from the queue");
   6774             if (m_input_free_q.m_size) {
   6775                 m_input_free_q.pop_entry(&address,&p2,&id);
   6776                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   6777                 pdest_frame->nFilledLen = 0;
   6778                 pdest_frame->nTimeStamp = LLONG_MAX;
   6779                 DEBUG_PRINT_LOW("\n Address of Pmem Buffer %p",pdest_frame);
   6780             }
   6781         }
   6782 
   6783         /*Check if we have a destination buffer*/
   6784         if (psource_frame == NULL) {
   6785             DEBUG_PRINT_LOW("\n Get a source buffer from the queue");
   6786             if (m_input_pending_q.m_size) {
   6787                 m_input_pending_q.pop_entry(&address,&p2,&id);
   6788                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   6789                 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
   6790                         psource_frame->nTimeStamp);
   6791                 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
   6792                         psource_frame->nFlags,psource_frame->nFilledLen);
   6793 
   6794             }
   6795         }
   6796 
   6797     }
   6798 
   6799     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   6800         switch (codec_type_parse) {
   6801             case CODEC_TYPE_MPEG4:
   6802             case CODEC_TYPE_H263:
   6803             case CODEC_TYPE_MPEG2:
   6804                 ret =  push_input_sc_codec(hComp);
   6805                 break;
   6806             case CODEC_TYPE_H264:
   6807                 ret = push_input_h264(hComp);
   6808                 break;
   6809             case CODEC_TYPE_VC1:
   6810                 ret = push_input_vc1(hComp);
   6811                 break;
   6812             default:
   6813                 break;
   6814         }
   6815         if (ret != OMX_ErrorNone) {
   6816             DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
   6817             omx_report_error ();
   6818             break;
   6819         }
   6820     }
   6821 
   6822     return ret;
   6823 }
   6824 
   6825 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   6826 {
   6827     OMX_U32 partial_frame = 1;
   6828     OMX_BOOL generate_ebd = OMX_TRUE;
   6829     unsigned address = 0, p2 = 0, id = 0;
   6830 
   6831     DEBUG_PRINT_LOW("\n Start Parsing the bit stream address %p TimeStamp %lld",
   6832             psource_frame,psource_frame->nTimeStamp);
   6833     if (m_frame_parser.parse_sc_frame(psource_frame,
   6834                 pdest_frame,&partial_frame) == -1) {
   6835         DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
   6836         return OMX_ErrorBadParameter;
   6837     }
   6838 
   6839     if (partial_frame == 0) {
   6840         DEBUG_PRINT_LOW("\n Frame size %lu source %p frame count %d",
   6841                 pdest_frame->nFilledLen,psource_frame,frame_count);
   6842 
   6843 
   6844         DEBUG_PRINT_LOW("\n TimeStamp updated %lld", pdest_frame->nTimeStamp);
   6845         /*First Parsed buffer will have only header Hence skip*/
   6846         if (frame_count == 0) {
   6847             DEBUG_PRINT_LOW("\n H263/MPEG4 Codec First Frame ");
   6848 
   6849             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   6850                     codec_type_parse == CODEC_TYPE_DIVX) {
   6851                 mp4StreamType psBits;
   6852                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   6853                 psBits.numBytes = pdest_frame->nFilledLen;
   6854                 mp4_headerparser.parseHeader(&psBits);
   6855             }
   6856 
   6857             frame_count++;
   6858         } else {
   6859             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   6860             if (pdest_frame->nFilledLen) {
   6861                 /*Push the frame to the Decoder*/
   6862                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   6863                     return OMX_ErrorBadParameter;
   6864                 }
   6865                 frame_count++;
   6866                 pdest_frame = NULL;
   6867 
   6868                 if (m_input_free_q.m_size) {
   6869                     m_input_free_q.pop_entry(&address,&p2,&id);
   6870                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   6871                     pdest_frame->nFilledLen = 0;
   6872                 }
   6873             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   6874                 DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
   6875                 m_input_free_q.insert_entry((unsigned) pdest_frame, (unsigned)NULL,
   6876                         (unsigned)NULL);
   6877                 pdest_frame = NULL;
   6878             }
   6879         }
   6880     } else {
   6881         DEBUG_PRINT_LOW("\n Not a Complete Frame %lu",pdest_frame->nFilledLen);
   6882         /*Check if Destination Buffer is full*/
   6883         if (pdest_frame->nAllocLen ==
   6884                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   6885             DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
   6886             return OMX_ErrorStreamCorrupt;
   6887         }
   6888     }
   6889 
   6890     if (psource_frame->nFilledLen == 0) {
   6891         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   6892             if (pdest_frame) {
   6893                 pdest_frame->nFlags |= psource_frame->nFlags;
   6894                 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %lld",
   6895                         pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   6896                 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
   6897                         pdest_frame->nFilledLen,frame_count++);
   6898                 /*Push the frame to the Decoder*/
   6899                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   6900                     return OMX_ErrorBadParameter;
   6901                 }
   6902                 frame_count++;
   6903                 pdest_frame = NULL;
   6904             } else {
   6905                 DEBUG_PRINT_LOW("\n Last frame in else dest addr") ;
   6906                 generate_ebd = OMX_FALSE;
   6907             }
   6908         }
   6909         if (generate_ebd) {
   6910             DEBUG_PRINT_LOW("\n Buffer Consumed return back to client %p",psource_frame);
   6911             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   6912             psource_frame = NULL;
   6913 
   6914             if (m_input_pending_q.m_size) {
   6915                 DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
   6916                 m_input_pending_q.pop_entry(&address,&p2,&id);
   6917                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   6918                 DEBUG_PRINT_LOW("\n Next source Buffer %p time stamp %lld",psource_frame,
   6919                         psource_frame->nTimeStamp);
   6920                 DEBUG_PRINT_LOW("\n Next source Buffer flag %lu length %lu",
   6921                         psource_frame->nFlags,psource_frame->nFilledLen);
   6922             }
   6923         }
   6924     }
   6925     return OMX_ErrorNone;
   6926 }
   6927 
   6928 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   6929 {
   6930     OMX_U32 partial_frame = 1;
   6931     unsigned address = 0, p2 = 0, id = 0;
   6932     OMX_BOOL isNewFrame = OMX_FALSE;
   6933     OMX_BOOL generate_ebd = OMX_TRUE;
   6934 
   6935     if (h264_scratch.pBuffer == NULL) {
   6936         DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
   6937         return OMX_ErrorBadParameter;
   6938     }
   6939     DEBUG_PRINT_LOW("\n Pending h264_scratch.nFilledLen %lu "
   6940             "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
   6941     DEBUG_PRINT_LOW("\n Pending pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
   6942     if (h264_scratch.nFilledLen && look_ahead_nal) {
   6943         look_ahead_nal = false;
   6944         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   6945                 h264_scratch.nFilledLen) {
   6946             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   6947                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   6948             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   6949             DEBUG_PRINT_LOW("\n Copy the previous NAL (h264 scratch) into Dest frame");
   6950             h264_scratch.nFilledLen = 0;
   6951         } else {
   6952             DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
   6953             return OMX_ErrorBadParameter;
   6954         }
   6955     }
   6956 
   6957     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   6958        in EOS flag getting associated with the destination
   6959     */
   6960     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   6961             pdest_frame->nFilledLen) {
   6962         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   6963         generate_ebd = OMX_FALSE;
   6964     }
   6965 
   6966     if (nal_length == 0) {
   6967         DEBUG_PRINT_LOW("\n Zero NAL, hence parse using start code");
   6968         if (m_frame_parser.parse_sc_frame(psource_frame,
   6969                     &h264_scratch,&partial_frame) == -1) {
   6970             DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
   6971             return OMX_ErrorBadParameter;
   6972         }
   6973     } else {
   6974         DEBUG_PRINT_LOW("\n Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   6975         if (m_frame_parser.parse_h264_nallength(psource_frame,
   6976                     &h264_scratch,&partial_frame) == -1) {
   6977             DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
   6978             return OMX_ErrorBadParameter;
   6979         }
   6980     }
   6981 
   6982     if (partial_frame == 0) {
   6983         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   6984             DEBUG_PRINT_LOW("\n First NAL with Zero Length, hence Skip");
   6985             nal_count++;
   6986             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   6987             h264_scratch.nFlags = psource_frame->nFlags;
   6988         } else {
   6989             DEBUG_PRINT_LOW("\n Parsed New NAL Length = %lu",h264_scratch.nFilledLen);
   6990             if (h264_scratch.nFilledLen) {
   6991                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   6992                         NALU_TYPE_SPS);
   6993 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   6994                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   6995                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   6996                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   6997                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   6998                     // If timeinfo is present frame info from SEI is already processed
   6999                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   7000                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   7001 #endif
   7002                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   7003                 nal_count++;
   7004                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   7005                     pdest_frame->nTimeStamp = h264_last_au_ts;
   7006                     pdest_frame->nFlags = h264_last_au_flags;
   7007 #ifdef PANSCAN_HDLR
   7008                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   7009                         h264_parser->update_panscan_data(h264_last_au_ts);
   7010 #endif
   7011                 }
   7012                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   7013                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   7014                     h264_last_au_ts = h264_scratch.nTimeStamp;
   7015                     h264_last_au_flags = h264_scratch.nFlags;
   7016 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   7017                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   7018                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   7019                         if (!VALID_TS(h264_last_au_ts))
   7020                             h264_last_au_ts = ts_in_sei;
   7021                     }
   7022 #endif
   7023                 } else
   7024                     h264_last_au_ts = LLONG_MAX;
   7025             }
   7026 
   7027             if (!isNewFrame) {
   7028                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7029                         h264_scratch.nFilledLen) {
   7030                     DEBUG_PRINT_LOW("\n Not a NewFrame Copy into Dest len %lu",
   7031                             h264_scratch.nFilledLen);
   7032                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7033                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7034                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7035                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   7036                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7037                     h264_scratch.nFilledLen = 0;
   7038                 } else {
   7039                     DEBUG_PRINT_LOW("\n Error:2: Destination buffer overflow for H264");
   7040                     return OMX_ErrorBadParameter;
   7041                 }
   7042             } else if(h264_scratch.nFilledLen) {
   7043                 look_ahead_nal = true;
   7044                 DEBUG_PRINT_LOW("\n Frame Found start Decoding Size =%lu TimeStamp = %llx",
   7045                         pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   7046                 DEBUG_PRINT_LOW("\n Found a frame size = %lu number = %d",
   7047                         pdest_frame->nFilledLen,frame_count++);
   7048 
   7049                 if (pdest_frame->nFilledLen == 0) {
   7050                     DEBUG_PRINT_LOW("\n Copy the Current Frame since and push it");
   7051                     look_ahead_nal = false;
   7052                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7053                             h264_scratch.nFilledLen) {
   7054                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7055                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7056                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7057                         h264_scratch.nFilledLen = 0;
   7058                     } else {
   7059                         DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
   7060                         return OMX_ErrorBadParameter;
   7061                     }
   7062                 } else {
   7063                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   7064                         DEBUG_PRINT_LOW("\n Reset the EOS Flag");
   7065                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   7066                     }
   7067                     /*Push the frame to the Decoder*/
   7068                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   7069                         return OMX_ErrorBadParameter;
   7070                     }
   7071                     //frame_count++;
   7072                     pdest_frame = NULL;
   7073                     if (m_input_free_q.m_size) {
   7074                         m_input_free_q.pop_entry(&address,&p2,&id);
   7075                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   7076                         DEBUG_PRINT_LOW("\n Pop the next pdest_buffer %p",pdest_frame);
   7077                         pdest_frame->nFilledLen = 0;
   7078                         pdest_frame->nFlags = 0;
   7079                         pdest_frame->nTimeStamp = LLONG_MAX;
   7080                     }
   7081                 }
   7082             }
   7083         }
   7084     } else {
   7085         DEBUG_PRINT_LOW("\n Not a Complete Frame, pdest_frame->nFilledLen %lu",pdest_frame->nFilledLen);
   7086         /*Check if Destination Buffer is full*/
   7087         if (h264_scratch.nAllocLen ==
   7088                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   7089             DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
   7090             return OMX_ErrorStreamCorrupt;
   7091         }
   7092     }
   7093 
   7094     if (!psource_frame->nFilledLen) {
   7095         DEBUG_PRINT_LOW("\n Buffer Consumed return source %p back to client",psource_frame);
   7096 
   7097         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   7098             if (pdest_frame) {
   7099                 DEBUG_PRINT_LOW("\n EOS Reached Pass Last Buffer");
   7100                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7101                         h264_scratch.nFilledLen) {
   7102                     if(pdest_frame->nFilledLen == 0) {
   7103                         /* No residual frame from before, send whatever
   7104                          * we have left */
   7105                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7106                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   7107                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7108                         h264_scratch.nFilledLen = 0;
   7109                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   7110                     } else {
   7111                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   7112                         if(!isNewFrame) {
   7113                             /* Have a residual frame, but we know that the
   7114                              * AU in this frame is belonging to whatever
   7115                              * frame we had left over.  So append it */
   7116                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7117                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7118                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7119                              h264_scratch.nFilledLen = 0;
   7120                              pdest_frame->nTimeStamp = h264_last_au_ts;
   7121                         } else {
   7122                             /* Completely new frame, let's just push what
   7123                              * we have now.  The resulting EBD would trigger
   7124                              * another push */
   7125                             generate_ebd = OMX_FALSE;
   7126                             pdest_frame->nTimeStamp = h264_last_au_ts;
   7127                             h264_last_au_ts = h264_scratch.nTimeStamp;
   7128                         }
   7129                     }
   7130                 } else {
   7131                     DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
   7132                     return OMX_ErrorBadParameter;
   7133                 }
   7134 
   7135                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   7136                 if(generate_ebd == OMX_TRUE) {
   7137                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   7138                 }
   7139 
   7140                 DEBUG_PRINT_LOW("\n pdest_frame->nFilledLen =%lu TimeStamp = %llx",
   7141                         pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   7142                 DEBUG_PRINT_LOW("\n Push AU frame number %d to driver", frame_count++);
   7143 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   7144                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   7145                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   7146                     if (!VALID_TS(pdest_frame->nTimeStamp))
   7147                         pdest_frame->nTimeStamp = ts_in_sei;
   7148                 }
   7149 #endif
   7150                 /*Push the frame to the Decoder*/
   7151                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   7152                     return OMX_ErrorBadParameter;
   7153                 }
   7154                 frame_count++;
   7155                 pdest_frame = NULL;
   7156             } else {
   7157                 DEBUG_PRINT_LOW("\n Last frame in else dest addr %p size %lu",
   7158                         pdest_frame,h264_scratch.nFilledLen);
   7159                 generate_ebd = OMX_FALSE;
   7160             }
   7161         }
   7162     }
   7163     if (generate_ebd && !psource_frame->nFilledLen) {
   7164         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   7165         psource_frame = NULL;
   7166         if (m_input_pending_q.m_size) {
   7167             DEBUG_PRINT_LOW("\n Pull Next source Buffer %p",psource_frame);
   7168             m_input_pending_q.pop_entry(&address,&p2,&id);
   7169             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   7170             DEBUG_PRINT_LOW("\nNext source Buffer flag %lu src length %lu",
   7171                     psource_frame->nFlags,psource_frame->nFilledLen);
   7172         }
   7173     }
   7174     return OMX_ErrorNone;
   7175 }
   7176 
   7177 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
   7178 {
   7179     OMX_U8 *buf, *pdest;
   7180     OMX_U32 partial_frame = 1;
   7181     OMX_U32 buf_len, dest_len;
   7182 
   7183     if (first_frame == 0) {
   7184         first_frame = 1;
   7185         DEBUG_PRINT_LOW("\nFirst i/p buffer for VC1 arbitrary bytes\n");
   7186         if (!m_vendor_config.pData) {
   7187             DEBUG_PRINT_LOW("\nCheck profile type in 1st source buffer\n");
   7188             buf = psource_frame->pBuffer;
   7189             buf_len = psource_frame->nFilledLen;
   7190 
   7191             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   7192                     VC1_SP_MP_START_CODE) {
   7193                 m_vc1_profile = VC1_SP_MP_RCV;
   7194             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   7195                 m_vc1_profile = VC1_AP;
   7196             } else {
   7197                 DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer\n");
   7198                 return OMX_ErrorStreamCorrupt;
   7199             }
   7200         } else {
   7201             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   7202                 pdest_frame->nOffset;
   7203             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   7204                     pdest_frame->nOffset);
   7205 
   7206             if (dest_len < m_vendor_config.nDataSize) {
   7207                 DEBUG_PRINT_ERROR("\nDestination buffer full\n");
   7208                 return OMX_ErrorBadParameter;
   7209             } else {
   7210                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   7211                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   7212             }
   7213         }
   7214     }
   7215 
   7216     switch (m_vc1_profile) {
   7217         case VC1_AP:
   7218             DEBUG_PRINT_LOW("\n VC1 AP, hence parse using frame start code");
   7219             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   7220                 DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
   7221                 return OMX_ErrorBadParameter;
   7222             }
   7223             break;
   7224 
   7225         case VC1_SP_MP_RCV:
   7226         default:
   7227             DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode\n");
   7228             return OMX_ErrorBadParameter;
   7229     }
   7230     return OMX_ErrorNone;
   7231 }
   7232 
   7233 #ifndef USE_ION
   7234 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   7235         OMX_U32 alignment)
   7236 {
   7237     struct pmem_allocation allocation;
   7238     allocation.size = buffer_size;
   7239     allocation.align = clip2(alignment);
   7240     if (allocation.align < 4096) {
   7241         allocation.align = 4096;
   7242     }
   7243     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   7244         DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
   7245                 allocation.align, allocation.size);
   7246         return false;
   7247     }
   7248     return true;
   7249 }
   7250 #endif
   7251 #ifdef USE_ION
   7252 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   7253         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   7254         struct ion_fd_data *fd_data, int flag)
   7255 {
   7256     int fd = -EINVAL;
   7257     int rc = -EINVAL;
   7258     int ion_dev_flag;
   7259     struct vdec_ion ion_buf_info;
   7260     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   7261         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
   7262         return -EINVAL;
   7263     }
   7264     ion_dev_flag = O_RDONLY;
   7265     fd = open (MEM_DEVICE, ion_dev_flag);
   7266     if (fd < 0) {
   7267         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
   7268         return fd;
   7269     }
   7270     alloc_data->flags = 0;
   7271     if (!secure_mode && (flag & ION_FLAG_CACHED)) {
   7272         alloc_data->flags |= ION_FLAG_CACHED;
   7273     }
   7274     alloc_data->len = buffer_size;
   7275     alloc_data->align = clip2(alignment);
   7276     if (alloc_data->align < 4096) {
   7277         alloc_data->align = 4096;
   7278     }
   7279     if ((secure_mode) && (flag & ION_SECURE))
   7280         alloc_data->flags |= ION_SECURE;
   7281 
   7282     alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   7283     if (secure_mode)
   7284         alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
   7285     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   7286     if (rc || !alloc_data->handle) {
   7287         DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
   7288         alloc_data->handle = NULL;
   7289         close(fd);
   7290         fd = -ENOMEM;
   7291         return fd;
   7292     }
   7293     fd_data->handle = alloc_data->handle;
   7294     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   7295     if (rc) {
   7296         DEBUG_PRINT_ERROR("\n ION MAP failed ");
   7297         ion_buf_info.ion_alloc_data = *alloc_data;
   7298         ion_buf_info.ion_device_fd = fd;
   7299         ion_buf_info.fd_ion_data = *fd_data;
   7300         free_ion_memory(&ion_buf_info);
   7301         fd_data->fd =-1;
   7302         close(fd);
   7303         fd = -ENOMEM;
   7304     }
   7305 
   7306     return fd;
   7307 }
   7308 
   7309 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   7310 {
   7311 
   7312     if (!buf_ion_info) {
   7313         DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
   7314         return;
   7315     }
   7316     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   7317                 &buf_ion_info->ion_alloc_data.handle)) {
   7318         DEBUG_PRINT_ERROR("\n ION: free failed" );
   7319     }
   7320     close(buf_ion_info->ion_device_fd);
   7321     buf_ion_info->ion_device_fd = -1;
   7322     buf_ion_info->ion_alloc_data.handle = NULL;
   7323     buf_ion_info->fd_ion_data.fd = -1;
   7324 }
   7325 #endif
   7326 void omx_vdec::free_output_buffer_header()
   7327 {
   7328     DEBUG_PRINT_HIGH("\n ALL output buffers are freed/released");
   7329     output_use_buffer = false;
   7330     ouput_egl_buffers = false;
   7331 
   7332     if (m_out_mem_ptr) {
   7333         free (m_out_mem_ptr);
   7334         m_out_mem_ptr = NULL;
   7335     }
   7336 
   7337     if (m_platform_list) {
   7338         free(m_platform_list);
   7339         m_platform_list = NULL;
   7340     }
   7341 
   7342     if (drv_ctx.ptr_respbuffer) {
   7343         free (drv_ctx.ptr_respbuffer);
   7344         drv_ctx.ptr_respbuffer = NULL;
   7345     }
   7346     if (drv_ctx.ptr_outputbuffer) {
   7347         free (drv_ctx.ptr_outputbuffer);
   7348         drv_ctx.ptr_outputbuffer = NULL;
   7349     }
   7350 #ifdef USE_ION
   7351     if (drv_ctx.op_buf_ion_info) {
   7352         DEBUG_PRINT_LOW("\n Free o/p ion context");
   7353         free(drv_ctx.op_buf_ion_info);
   7354         drv_ctx.op_buf_ion_info = NULL;
   7355     }
   7356 #endif
   7357     if (out_dynamic_list) {
   7358         free(out_dynamic_list);
   7359         out_dynamic_list = NULL;
   7360     }
   7361 }
   7362 
   7363 void omx_vdec::free_input_buffer_header()
   7364 {
   7365     input_use_buffer = false;
   7366     if (arbitrary_bytes) {
   7367         if (m_inp_heap_ptr) {
   7368             DEBUG_PRINT_LOW("\n Free input Heap Pointer");
   7369             free (m_inp_heap_ptr);
   7370             m_inp_heap_ptr = NULL;
   7371         }
   7372 
   7373         if (m_phdr_pmem_ptr) {
   7374             DEBUG_PRINT_LOW("\n Free input pmem header Pointer");
   7375             free (m_phdr_pmem_ptr);
   7376             m_phdr_pmem_ptr = NULL;
   7377         }
   7378     }
   7379     if (m_inp_mem_ptr) {
   7380         DEBUG_PRINT_LOW("\n Free input pmem Pointer area");
   7381         free (m_inp_mem_ptr);
   7382         m_inp_mem_ptr = NULL;
   7383     }
   7384     /* We just freed all the buffer headers, every thing in m_input_free_q,
   7385      * pdest_frame, and psource_frame is now invalid */
   7386     while (m_input_free_q.m_size) {
   7387         unsigned address, p2, id;
   7388         m_input_free_q.pop_entry(&address, &p2, &id);
   7389     }
   7390     /* We just freed all the buffer headers, every thing in m_input_pending_q,
   7391      * is now invalid too*/
   7392     while (m_input_pending_q.m_size) {
   7393         unsigned address, p2, id;
   7394         m_input_pending_q.pop_entry(&address, &p2, &id);
   7395     }
   7396     pdest_frame = NULL;
   7397     psource_frame = NULL;
   7398     if (drv_ctx.ptr_inputbuffer) {
   7399         DEBUG_PRINT_LOW("\n Free Driver Context pointer");
   7400         free (drv_ctx.ptr_inputbuffer);
   7401         drv_ctx.ptr_inputbuffer = NULL;
   7402     }
   7403 #ifdef USE_ION
   7404     if (drv_ctx.ip_buf_ion_info) {
   7405         DEBUG_PRINT_LOW("\n Free ion context");
   7406         free(drv_ctx.ip_buf_ion_info);
   7407         drv_ctx.ip_buf_ion_info = NULL;
   7408     }
   7409 #endif
   7410 }
   7411 
   7412 int omx_vdec::stream_off(OMX_U32 port)
   7413 {
   7414     enum v4l2_buf_type btype;
   7415     int rc = 0;
   7416     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   7417 
   7418     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   7419         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7420         v4l2_port = OUTPUT_PORT;
   7421     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   7422         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7423         v4l2_port = CAPTURE_PORT;
   7424     } else if (port == OMX_ALL) {
   7425         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   7426         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   7427 
   7428         if (!rc_input)
   7429             return rc_input;
   7430         else
   7431             return rc_output;
   7432     }
   7433 
   7434     if (!streaming[v4l2_port]) {
   7435         // already streamed off, warn and move on
   7436         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   7437                 " which is already streamed off", v4l2_port);
   7438         return 0;
   7439     }
   7440 
   7441     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   7442 
   7443     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   7444     if (rc) {
   7445         /*TODO: How to handle this case */
   7446         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port \n", v4l2_port);
   7447     } else {
   7448         streaming[v4l2_port] = false;
   7449     }
   7450 
   7451     return rc;
   7452 }
   7453 
   7454 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   7455 {
   7456     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7457     struct v4l2_requestbuffers bufreq;
   7458     unsigned int buf_size = 0, extra_data_size = 0, client_extra_data_size = 0;
   7459     struct v4l2_format fmt;
   7460     int ret = 0;
   7461     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
   7462             buffer_prop->actualcount, buffer_prop->buffer_size);
   7463     bufreq.memory = V4L2_MEMORY_USERPTR;
   7464     bufreq.count = 1;
   7465     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   7466         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7467         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7468         fmt.fmt.pix_mp.pixelformat = output_capability;
   7469     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   7470         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7471         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7472         fmt.fmt.pix_mp.pixelformat = capture_capability;
   7473     } else {
   7474         eRet = OMX_ErrorBadParameter;
   7475     }
   7476     if (eRet==OMX_ErrorNone) {
   7477         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   7478     }
   7479     if (ret) {
   7480         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   7481         /*TODO: How to handle this case */
   7482         eRet = OMX_ErrorInsufficientResources;
   7483         return eRet;
   7484     } else {
   7485         buffer_prop->actualcount = bufreq.count;
   7486         buffer_prop->mincount = bufreq.count;
   7487         DEBUG_PRINT_HIGH("Count = %d \n ",bufreq.count);
   7488     }
   7489     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
   7490             buffer_prop->actualcount, buffer_prop->buffer_size);
   7491 
   7492     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   7493     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   7494 
   7495     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   7496 
   7497     update_resolution(fmt.fmt.pix_mp.width,
   7498             fmt.fmt.pix_mp.height,
   7499             fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
   7500             fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   7501     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   7502         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   7503     DEBUG_PRINT_HIGH("Buffer Size = %d \n ",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   7504 
   7505     if (ret) {
   7506         /*TODO: How to handle this case */
   7507         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   7508         eRet = OMX_ErrorInsufficientResources;
   7509     } else {
   7510         int extra_idx = 0;
   7511 
   7512         eRet = is_video_session_supported();
   7513         if (eRet)
   7514             return eRet;
   7515 
   7516         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   7517         buf_size = buffer_prop->buffer_size;
   7518         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   7519         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   7520             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   7521         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   7522             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d\n", extra_idx);
   7523             return OMX_ErrorBadParameter;
   7524         }
   7525         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   7526             DEBUG_PRINT_HIGH("Frame info extra data enabled!");
   7527             client_extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
   7528         }
   7529         if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   7530             client_extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
   7531         }
   7532         if (client_extradata & OMX_PORTDEF_EXTRADATA) {
   7533             client_extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
   7534             DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d\n",
   7535                     client_extra_data_size);
   7536         }
   7537         if (client_extra_data_size) {
   7538             client_extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
   7539             buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
   7540         }
   7541         drv_ctx.extradata_info.size = buffer_prop->actualcount * extra_data_size;
   7542         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   7543         drv_ctx.extradata_info.buffer_size = extra_data_size;
   7544         buf_size += client_extra_data_size;
   7545         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   7546         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
   7547                 buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
   7548         if (in_reconfig) // BufReq will be set to driver when port is disabled
   7549             buffer_prop->buffer_size = buf_size;
   7550         else if (buf_size != buffer_prop->buffer_size) {
   7551             buffer_prop->buffer_size = buf_size;
   7552             eRet = set_buffer_req(buffer_prop);
   7553         }
   7554     }
   7555     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
   7556             buffer_prop->actualcount, buffer_prop->buffer_size);
   7557     return eRet;
   7558 }
   7559 
   7560 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   7561 {
   7562     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7563     unsigned buf_size = 0;
   7564     struct v4l2_format fmt;
   7565     struct v4l2_requestbuffers bufreq;
   7566     int ret;
   7567     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
   7568             buffer_prop->actualcount, buffer_prop->buffer_size);
   7569     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   7570     if (buf_size != buffer_prop->buffer_size) {
   7571         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
   7572                 buffer_prop->buffer_size, buf_size);
   7573         eRet = OMX_ErrorBadParameter;
   7574     } else {
   7575         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   7576         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   7577 
   7578         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   7579             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7580             fmt.fmt.pix_mp.pixelformat = output_capability;
   7581         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   7582             fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7583             fmt.fmt.pix_mp.pixelformat = capture_capability;
   7584         } else {
   7585             eRet = OMX_ErrorBadParameter;
   7586         }
   7587 
   7588         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   7589         if (ret) {
   7590             /*TODO: How to handle this case */
   7591             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   7592             eRet = OMX_ErrorInsufficientResources;
   7593         }
   7594 
   7595         bufreq.memory = V4L2_MEMORY_USERPTR;
   7596         bufreq.count = buffer_prop->actualcount;
   7597         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   7598             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7599         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   7600             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7601         } else {
   7602             eRet = OMX_ErrorBadParameter;
   7603         }
   7604 
   7605         if (eRet==OMX_ErrorNone) {
   7606             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   7607         }
   7608 
   7609         if (ret) {
   7610             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   7611             /*TODO: How to handle this case */
   7612             eRet = OMX_ErrorInsufficientResources;
   7613         } else if (bufreq.count < buffer_prop->actualcount) {
   7614             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   7615                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   7616                     buffer_prop->actualcount, bufreq.count);
   7617             eRet = OMX_ErrorInsufficientResources;
   7618         } else {
   7619             if (!client_buffers.update_buffer_req()) {
   7620                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   7621                 eRet = OMX_ErrorInsufficientResources;
   7622             }
   7623         }
   7624     }
   7625     return eRet;
   7626 }
   7627 
   7628 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   7629 {
   7630     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7631     return eRet;
   7632 }
   7633 
   7634 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   7635 {
   7636     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7637     if (!portDefn) {
   7638         return OMX_ErrorBadParameter;
   7639     }
   7640     DEBUG_PRINT_LOW("omx_vdec::update_portdef\n");
   7641     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   7642     portDefn->nSize = sizeof(portDefn);
   7643     portDefn->eDomain    = OMX_PortDomainVideo;
   7644     if (drv_ctx.frame_rate.fps_denominator > 0)
   7645         portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
   7646             drv_ctx.frame_rate.fps_denominator;
   7647     else {
   7648         DEBUG_PRINT_ERROR("Error: Divide by zero \n");
   7649         return OMX_ErrorBadParameter;
   7650     }
   7651     if (0 == portDefn->nPortIndex) {
   7652         portDefn->eDir =  OMX_DirInput;
   7653         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   7654         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   7655         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   7656         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   7657         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   7658         portDefn->bEnabled   = m_inp_bEnabled;
   7659         portDefn->bPopulated = m_inp_bPopulated;
   7660     } else if (1 == portDefn->nPortIndex) {
   7661         unsigned int buf_size = 0;
   7662         if (!client_buffers.update_buffer_req()) {
   7663             DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
   7664             return OMX_ErrorHardware;
   7665         }
   7666         if (!client_buffers.get_buffer_req(buf_size)) {
   7667             DEBUG_PRINT_ERROR("\n update buffer requirements");
   7668             return OMX_ErrorHardware;
   7669         }
   7670         portDefn->nBufferSize = buf_size;
   7671         portDefn->eDir =  OMX_DirOutput;
   7672         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   7673         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   7674         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   7675         portDefn->bEnabled   = m_out_bEnabled;
   7676         portDefn->bPopulated = m_out_bPopulated;
   7677         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   7678             DEBUG_PRINT_ERROR("\n Error in getting color format");
   7679             return OMX_ErrorHardware;
   7680         }
   7681     } else {
   7682         portDefn->eDir = OMX_DirMax;
   7683         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   7684                 (int)portDefn->nPortIndex);
   7685         eRet = OMX_ErrorBadPortIndex;
   7686     }
   7687     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   7688     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   7689     portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   7690     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   7691     DEBUG_PRINT_HIGH("update_portdef Width = %lu Height = %lu Stride = %ld"
   7692             " SliceHeight = %lu \n", portDefn->format.video.nFrameWidth,
   7693             portDefn->format.video.nFrameHeight,
   7694             portDefn->format.video.nStride,
   7695             portDefn->format.video.nSliceHeight);
   7696     return eRet;
   7697 
   7698 }
   7699 
   7700 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   7701 {
   7702     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7703     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   7704     unsigned i= 0;
   7705 
   7706     if (!m_out_mem_ptr) {
   7707         DEBUG_PRINT_HIGH("\n Use o/p buffer case - Header List allocation");
   7708         int nBufHdrSize        = 0;
   7709         int nPlatformEntrySize = 0;
   7710         int nPlatformListSize  = 0;
   7711         int nPMEMInfoSize = 0;
   7712         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   7713         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   7714         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   7715 
   7716         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)\n",
   7717                 drv_ctx.op_buf.actualcount);
   7718         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   7719             sizeof(OMX_BUFFERHEADERTYPE);
   7720 
   7721         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   7722             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   7723         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   7724             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   7725         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   7726             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   7727 
   7728         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d\n",nBufHdrSize,
   7729                 sizeof(OMX_BUFFERHEADERTYPE),
   7730                 nPMEMInfoSize,
   7731                 nPlatformListSize);
   7732         DEBUG_PRINT_LOW("PE %d bmSize %d \n",nPlatformEntrySize,
   7733                 m_out_bm_count);
   7734         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   7735         // Alloc mem for platform specific info
   7736         char *pPtr=NULL;
   7737         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   7738                 nPMEMInfoSize,1);
   7739         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   7740                        calloc (sizeof(struct vdec_bufferpayload),
   7741                                drv_ctx.op_buf.actualcount);
   7742         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   7743                      calloc (sizeof (struct vdec_output_frameinfo),
   7744                              drv_ctx.op_buf.actualcount);
   7745 #ifdef USE_ION
   7746         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   7747                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   7748 #endif
   7749         if (dynamic_buf_mode) {
   7750             out_dynamic_list = (struct dynamic_buf_list *) \
   7751                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   7752         }
   7753 
   7754         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   7755                 && drv_ctx.ptr_respbuffer) {
   7756             bufHdr          =  m_out_mem_ptr;
   7757             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   7758             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   7759                 (((char *) m_platform_list)  + nPlatformListSize);
   7760             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   7761                 (((char *) m_platform_entry) + nPlatformEntrySize);
   7762             pPlatformList   = m_platform_list;
   7763             pPlatformEntry  = m_platform_entry;
   7764             pPMEMInfo       = m_pmem_info;
   7765 
   7766             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
   7767 
   7768             // Settting the entire storage nicely
   7769             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p\n",bufHdr,
   7770                     m_out_mem_ptr,pPlatformEntry);
   7771             DEBUG_PRINT_LOW(" Pmem Info = %p \n",pPMEMInfo);
   7772             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   7773                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   7774                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   7775                 // Set the values when we determine the right HxW param
   7776                 bufHdr->nAllocLen          = 0;
   7777                 bufHdr->nFilledLen         = 0;
   7778                 bufHdr->pAppPrivate        = NULL;
   7779                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   7780                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   7781                 pPlatformEntry->entry      = pPMEMInfo;
   7782                 // Initialize the Platform List
   7783                 pPlatformList->nEntries    = 1;
   7784                 pPlatformList->entryList   = pPlatformEntry;
   7785                 // Keep pBuffer NULL till vdec is opened
   7786                 bufHdr->pBuffer            = NULL;
   7787                 pPMEMInfo->offset          =  0;
   7788                 pPMEMInfo->pmem_fd = 0;
   7789                 bufHdr->pPlatformPrivate = pPlatformList;
   7790                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   7791 #ifdef USE_ION
   7792                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   7793 #endif
   7794                 /*Create a mapping between buffers*/
   7795                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   7796                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   7797                                     &drv_ctx.ptr_outputbuffer[i];
   7798                 // Move the buffer and buffer header pointers
   7799                 bufHdr++;
   7800                 pPMEMInfo++;
   7801                 pPlatformEntry++;
   7802                 pPlatformList++;
   7803             }
   7804         } else {
   7805             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]\n",\
   7806                     m_out_mem_ptr, pPtr);
   7807             if (m_out_mem_ptr) {
   7808                 free(m_out_mem_ptr);
   7809                 m_out_mem_ptr = NULL;
   7810             }
   7811             if (pPtr) {
   7812                 free(pPtr);
   7813                 pPtr = NULL;
   7814             }
   7815             if (drv_ctx.ptr_outputbuffer) {
   7816                 free(drv_ctx.ptr_outputbuffer);
   7817                 drv_ctx.ptr_outputbuffer = NULL;
   7818             }
   7819             if (drv_ctx.ptr_respbuffer) {
   7820                 free(drv_ctx.ptr_respbuffer);
   7821                 drv_ctx.ptr_respbuffer = NULL;
   7822             }
   7823 #ifdef USE_ION
   7824             if (drv_ctx.op_buf_ion_info) {
   7825                 DEBUG_PRINT_LOW("\n Free o/p ion context");
   7826                 free(drv_ctx.op_buf_ion_info);
   7827                 drv_ctx.op_buf_ion_info = NULL;
   7828             }
   7829 #endif
   7830             eRet =  OMX_ErrorInsufficientResources;
   7831         }
   7832     } else {
   7833         eRet =  OMX_ErrorInsufficientResources;
   7834     }
   7835     return eRet;
   7836 }
   7837 
   7838 void omx_vdec::complete_pending_buffer_done_cbs()
   7839 {
   7840     unsigned p1;
   7841     unsigned p2;
   7842     unsigned ident;
   7843     omx_cmd_queue tmp_q, pending_bd_q;
   7844     pthread_mutex_lock(&m_lock);
   7845     // pop all pending GENERATE FDB from ftb queue
   7846     while (m_ftb_q.m_size) {
   7847         m_ftb_q.pop_entry(&p1,&p2,&ident);
   7848         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   7849             pending_bd_q.insert_entry(p1,p2,ident);
   7850         } else {
   7851             tmp_q.insert_entry(p1,p2,ident);
   7852         }
   7853     }
   7854     //return all non GENERATE FDB to ftb queue
   7855     while (tmp_q.m_size) {
   7856         tmp_q.pop_entry(&p1,&p2,&ident);
   7857         m_ftb_q.insert_entry(p1,p2,ident);
   7858     }
   7859     // pop all pending GENERATE EDB from etb queue
   7860     while (m_etb_q.m_size) {
   7861         m_etb_q.pop_entry(&p1,&p2,&ident);
   7862         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   7863             pending_bd_q.insert_entry(p1,p2,ident);
   7864         } else {
   7865             tmp_q.insert_entry(p1,p2,ident);
   7866         }
   7867     }
   7868     //return all non GENERATE FDB to etb queue
   7869     while (tmp_q.m_size) {
   7870         tmp_q.pop_entry(&p1,&p2,&ident);
   7871         m_etb_q.insert_entry(p1,p2,ident);
   7872     }
   7873     pthread_mutex_unlock(&m_lock);
   7874     // process all pending buffer dones
   7875     while (pending_bd_q.m_size) {
   7876         pending_bd_q.pop_entry(&p1,&p2,&ident);
   7877         switch (ident) {
   7878             case OMX_COMPONENT_GENERATE_EBD:
   7879                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   7880                     DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
   7881                     omx_report_error ();
   7882                 }
   7883                 break;
   7884 
   7885             case OMX_COMPONENT_GENERATE_FBD:
   7886                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   7887                     DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
   7888                     omx_report_error ();
   7889                 }
   7890                 break;
   7891         }
   7892     }
   7893 }
   7894 
   7895 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   7896 {
   7897     OMX_U32 new_frame_interval = 0;
   7898     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   7899             && llabs(act_timestamp - prev_ts) > 2000) {
   7900         new_frame_interval = client_set_fps ? frm_int :
   7901             llabs(act_timestamp - prev_ts);
   7902         if (new_frame_interval < frm_int || frm_int == 0) {
   7903             frm_int = new_frame_interval;
   7904             if (frm_int) {
   7905                 drv_ctx.frame_rate.fps_numerator = 1e6;
   7906                 drv_ctx.frame_rate.fps_denominator = frm_int;
   7907                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%lu) fps(%f)",
   7908                         frm_int, drv_ctx.frame_rate.fps_numerator /
   7909                         (float)drv_ctx.frame_rate.fps_denominator);
   7910 
   7911                 /* We need to report the difference between this FBD and the previous FBD
   7912                  * back to the driver for clock scaling purposes. */
   7913                 struct v4l2_outputparm oparm;
   7914                 /*XXX: we're providing timing info as seconds per frame rather than frames
   7915                  * per second.*/
   7916                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   7917                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   7918 
   7919                 struct v4l2_streamparm sparm;
   7920                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7921                 sparm.parm.output = oparm;
   7922                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   7923                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   7924                             performance might be affected");
   7925                 }
   7926 
   7927             }
   7928         }
   7929     }
   7930     prev_ts = act_timestamp;
   7931 }
   7932 
   7933 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   7934 {
   7935     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   7936         prev_ts = act_timestamp;
   7937         rst_prev_ts = false;
   7938     } else if (VALID_TS(prev_ts)) {
   7939         bool codec_cond = (drv_ctx.timestamp_adjust)?
   7940             (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
   7941                                (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
   7942             (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
   7943         if (frm_int > 0 && codec_cond) {
   7944             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   7945             act_timestamp = prev_ts + frm_int;
   7946             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   7947             prev_ts = act_timestamp;
   7948         } else
   7949             set_frame_rate(act_timestamp);
   7950     } else if (frm_int > 0)          // In this case the frame rate was set along
   7951     {                               // with the port definition, start ts with 0
   7952         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   7953         rst_prev_ts = true;
   7954     }
   7955 }
   7956 
   7957 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   7958 {
   7959     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
   7960     OMX_U32 num_conceal_MB = 0;
   7961     OMX_U32 frame_rate = 0;
   7962     int consumed_len = 0;
   7963     OMX_U32 num_MB_in_frame;
   7964     OMX_U32 recovery_sei_flags = 1;
   7965     int enable = 0;
   7966     OMX_U32 mbaff = 0;
   7967     int buf_index = p_buf_hdr - m_out_mem_ptr;
   7968     if (buf_index >= drv_ctx.extradata_info.count) {
   7969         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   7970                 buf_index, drv_ctx.extradata_info.count);
   7971         return;
   7972     }
   7973     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   7974     OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
   7975         p_buf_hdr->nOffset;
   7976 
   7977     auto_lock extradata_lock(&e_lock);
   7978 
   7979     if (!drv_ctx.extradata_info.uaddr) {
   7980         return;
   7981     }
   7982     p_extra = (OMX_OTHER_EXTRADATATYPE *)
   7983         ((unsigned)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   7984     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   7985     if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
   7986         p_extra = NULL;
   7987     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   7988     if (data) {
   7989         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   7990                 && (data->eType != (OMX_EXTRADATATYPE)EXTRADATA_NONE)) {
   7991             if ((consumed_len + data->nSize) > drv_ctx.extradata_info.buffer_size) {
   7992                 DEBUG_PRINT_LOW("Invalid extra data size");
   7993                 break;
   7994             }
   7995             switch ((unsigned long)data->eType) {
   7996                 case EXTRADATA_INTERLACE_VIDEO:
   7997                     struct msm_vidc_interlace_payload *payload;
   7998                     payload = (struct msm_vidc_interlace_payload *)data->data;
   7999                     mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
   8000                     if (payload && (payload->format == INTERLACE_FRAME_PROGRESSIVE)  && !mbaff)
   8001                         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   8002                     else {
   8003                         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   8004                         enable = 1;
   8005                     }
   8006                     if (m_enable_android_native_buffers) {
   8007                         private_handle_t *private_handle = native_buffer[buf_index].privatehandle;
   8008                         if (private_handle) {
   8009                             setMetaData(private_handle, PP_PARAM_INTERLACED, (void*)&enable);
   8010                         }
   8011                     }
   8012                     if (!secure_mode && (client_extradata & OMX_INTERLACE_EXTRADATA)) {
   8013                         append_interlace_extradata(p_extra, payload->format);
   8014                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   8015                     }
   8016                     break;
   8017                 case EXTRADATA_FRAME_RATE:
   8018                     struct msm_vidc_framerate_payload *frame_rate_payload;
   8019                     frame_rate_payload = (struct msm_vidc_framerate_payload *)data->data;
   8020                     frame_rate = frame_rate_payload->frame_rate;
   8021                     break;
   8022                 case EXTRADATA_TIMESTAMP:
   8023                     struct msm_vidc_ts_payload *time_stamp_payload;
   8024                     time_stamp_payload = (struct msm_vidc_ts_payload *)data->data;
   8025                     p_buf_hdr->nTimeStamp = time_stamp_payload->timestamp_lo;
   8026                     p_buf_hdr->nTimeStamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   8027                     break;
   8028                 case EXTRADATA_NUM_CONCEALED_MB:
   8029                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   8030                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)data->data;
   8031                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   8032                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   8033                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   8034                     break;
   8035                 case EXTRADATA_INDEX:
   8036                     int *etype;
   8037                     etype  = (int *)(data->data);
   8038                     if (etype && *etype == EXTRADATA_ASPECT_RATIO) {
   8039                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   8040                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   8041                         if (aspect_ratio_payload) {
   8042                             ((struct vdec_output_frameinfo *)
   8043                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   8044                             ((struct vdec_output_frameinfo *)
   8045                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   8046                         }
   8047                     }
   8048                     break;
   8049                 case EXTRADATA_RECOVERY_POINT_SEI:
   8050                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   8051                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)data->data;
   8052                     recovery_sei_flags = recovery_sei_payload->flags;
   8053                     if (recovery_sei_flags != FRAME_RECONSTRUCTION_CORRECT) {
   8054                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   8055                         DEBUG_PRINT_HIGH("\n");
   8056                         DEBUG_PRINT_HIGH("***************************************************\n");
   8057                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
   8058                         DEBUG_PRINT_HIGH("***************************************************\n");
   8059                     }
   8060                     break;
   8061                 case EXTRADATA_PANSCAN_WINDOW:
   8062                     panscan_payload = (struct msm_vidc_panscan_window_payload *)data->data;
   8063                     break;
   8064                 case EXTRADATA_MPEG2_SEQDISP:
   8065                     struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   8066                     seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data->data;
   8067                     if (seqdisp_payload) {
   8068                         m_disp_hor_size = seqdisp_payload->disp_width;
   8069                         m_disp_vert_size = seqdisp_payload->disp_height;
   8070                     }
   8071                     break;
   8072                 default:
   8073                     goto unrecognized_extradata;
   8074             }
   8075             consumed_len += data->nSize;
   8076             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   8077             if (data->nSize) {
   8078                 break;
   8079             }
   8080         }
   8081         if (!secure_mode && (client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   8082             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   8083             append_frame_info_extradata(p_extra,
   8084                     num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   8085                     panscan_payload,&((struct vdec_output_frameinfo *)
   8086                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   8087         }
   8088     }
   8089 unrecognized_extradata:
   8090     if (!secure_mode && client_extradata)
   8091         append_terminator_extradata(p_extra);
   8092     return;
   8093 }
   8094 
   8095 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
   8096         bool is_internal, bool enable)
   8097 {
   8098     OMX_ERRORTYPE ret = OMX_ErrorNone;
   8099     struct v4l2_control control;
   8100     if (m_state != OMX_StateLoaded) {
   8101         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   8102         return OMX_ErrorIncorrectStateOperation;
   8103     }
   8104     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%lu] requested[%lu] enable[%d], is_internal: %d\n",
   8105             client_extradata, requested_extradata, enable, is_internal);
   8106 
   8107     if (!is_internal) {
   8108         if (enable)
   8109             client_extradata |= requested_extradata;
   8110         else
   8111             client_extradata = client_extradata & ~requested_extradata;
   8112     }
   8113 
   8114     if (enable) {
   8115         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   8116             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8117             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   8118             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8119                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   8120                         " Quality of interlaced clips might be impacted.\n");
   8121             }
   8122         } else if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   8123             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8124             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   8125             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8126                 DEBUG_PRINT_HIGH("Failed to set framerate extradata\n");
   8127             }
   8128             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8129             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   8130             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8131                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata\n");
   8132             }
   8133             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8134             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   8135             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8136                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata\n");
   8137             }
   8138             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8139             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   8140             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8141                 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
   8142             }
   8143             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8144             control.value = V4L2_MPEG_VIDC_INDEX_EXTRADATA_ASPECT_RATIO;
   8145             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8146                 DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
   8147             }
   8148             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   8149                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8150                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   8151                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8152                     DEBUG_PRINT_HIGH("Failed to set panscan extradata\n");
   8153                 }
   8154             }
   8155         } else if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   8156             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   8157             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   8158             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   8159                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata\n");
   8160             }
   8161         }
   8162     }
   8163     ret = get_buffer_req(&drv_ctx.op_buf);
   8164     return ret;
   8165 }
   8166 
   8167 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   8168 {
   8169     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   8170     OMX_U8 *data_ptr = extra->data, data = 0;
   8171     while (byte_count < extra->nDataSize) {
   8172         data = *data_ptr;
   8173         while (data) {
   8174             num_MB += (data&0x01);
   8175             data >>= 1;
   8176         }
   8177         data_ptr++;
   8178         byte_count++;
   8179     }
   8180     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   8181             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   8182     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   8183 }
   8184 
   8185 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   8186 {
   8187     if (!m_debug_extradata)
   8188         return;
   8189 
   8190     DEBUG_PRINT_HIGH(
   8191             "============== Extra Data ==============\n"
   8192             "           Size: %lu \n"
   8193             "        Version: %lu \n"
   8194             "      PortIndex: %lu \n"
   8195             "           Type: %x \n"
   8196             "       DataSize: %lu \n",
   8197             extra->nSize, extra->nVersion.nVersion,
   8198             extra->nPortIndex, extra->eType, extra->nDataSize);
   8199 
   8200     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   8201         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
   8202         DEBUG_PRINT_HIGH(
   8203                 "------ Interlace Format ------\n"
   8204                 "                Size: %lu \n"
   8205                 "             Version: %lu \n"
   8206                 "           PortIndex: %lu \n"
   8207                 " Is Interlace Format: %d \n"
   8208                 "   Interlace Formats: %lu \n"
   8209                 "=========== End of Interlace ===========\n",
   8210                 intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
   8211                 intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
   8212     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   8213         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
   8214 
   8215         DEBUG_PRINT_HIGH(
   8216                 "-------- Frame Format --------\n"
   8217                 "             Picture Type: %d \n"
   8218                 "           Interlace Type: %d \n"
   8219                 " Pan Scan Total Frame Num: %lu \n"
   8220                 "   Concealed Macro Blocks: %lu \n"
   8221                 "               frame rate: %lu \n"
   8222                 "           Aspect Ratio X: %lu \n"
   8223                 "           Aspect Ratio Y: %lu \n",
   8224                 fminfo->ePicType,
   8225                 fminfo->interlaceType,
   8226                 fminfo->panScan.numWindows,
   8227                 fminfo->nConcealedMacroblocks,
   8228                 fminfo->nFrameRate,
   8229                 fminfo->aspectRatio.aspectRatioX,
   8230                 fminfo->aspectRatio.aspectRatioY);
   8231 
   8232         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   8233             DEBUG_PRINT_HIGH(
   8234                     "------------------------------\n"
   8235                     "     Pan Scan Frame Num: %lu \n"
   8236                     "            Rectangle x: %ld \n"
   8237                     "            Rectangle y: %ld \n"
   8238                     "           Rectangle dx: %ld \n"
   8239                     "           Rectangle dy: %ld \n",
   8240                     i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
   8241                     fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
   8242         }
   8243 
   8244         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   8245     } else if (extra->eType == OMX_ExtraDataNone) {
   8246         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   8247     } else {
   8248         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   8249     }
   8250 }
   8251 
   8252 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   8253         OMX_U32 interlaced_format_type)
   8254 {
   8255     OMX_STREAMINTERLACEFORMAT *interlace_format;
   8256     OMX_U32 mbaff = 0;
   8257     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   8258         return;
   8259     }
   8260     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   8261     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   8262     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   8263     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   8264     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   8265     interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
   8266     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   8267     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   8268     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   8269     mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
   8270     if ((interlaced_format_type == INTERLACE_FRAME_PROGRESSIVE)  && !mbaff) {
   8271         interlace_format->bInterlaceFormat = OMX_FALSE;
   8272         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   8273         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   8274     } else {
   8275         interlace_format->bInterlaceFormat = OMX_TRUE;
   8276         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   8277         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   8278     }
   8279     print_debug_extradata(extra);
   8280 }
   8281 
   8282 void omx_vdec::fill_aspect_ratio_info(
   8283         struct vdec_aspectratioinfo *aspect_ratio_info,
   8284         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   8285 {
   8286     m_extradata = frame_info;
   8287     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   8288     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   8289     DEBUG_PRINT_LOW("aspectRatioX %lu aspectRatioX %lu", m_extradata->aspectRatio.aspectRatioX,
   8290             m_extradata->aspectRatio.aspectRatioY);
   8291 }
   8292 
   8293 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   8294         OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
   8295         struct msm_vidc_panscan_window_payload *panscan_payload,
   8296         struct vdec_aspectratioinfo *aspect_ratio_info)
   8297 {
   8298     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   8299     struct msm_vidc_panscan_window *panscan_window;
   8300     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   8301         return;
   8302     }
   8303     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   8304     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   8305     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   8306     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   8307     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   8308     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
   8309     switch (picture_type) {
   8310         case PICTURE_TYPE_I:
   8311             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   8312             break;
   8313         case PICTURE_TYPE_P:
   8314             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   8315             break;
   8316         case PICTURE_TYPE_B:
   8317             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   8318             break;
   8319         default:
   8320             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   8321     }
   8322     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   8323         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   8324     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   8325         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   8326     else
   8327         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   8328     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   8329     frame_info->nConcealedMacroblocks = num_conceal_mb;
   8330     frame_info->nFrameRate = frame_rate;
   8331     frame_info->panScan.numWindows = 0;
   8332     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   8333         if (m_disp_hor_size && m_disp_vert_size) {
   8334             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   8335             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   8336         }
   8337     }
   8338 
   8339     if (panscan_payload) {
   8340         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   8341         panscan_window = &panscan_payload->wnd[0];
   8342         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   8343             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   8344             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   8345             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   8346             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   8347             panscan_window++;
   8348         }
   8349     }
   8350     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   8351     print_debug_extradata(extra);
   8352 }
   8353 
   8354 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   8355 {
   8356     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   8357     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   8358     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   8359     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   8360     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   8361     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   8362     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
   8363     *portDefn = m_port_def;
   8364     DEBUG_PRINT_LOW("append_portdef_extradata height = %lu width = %lu "
   8365             "stride = %lu sliceheight = %lu \n",portDefn->format.video.nFrameHeight,
   8366             portDefn->format.video.nFrameWidth,
   8367             portDefn->format.video.nStride,
   8368             portDefn->format.video.nSliceHeight);
   8369 }
   8370 
   8371 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   8372 {
   8373     if (!client_extradata) {
   8374         return;
   8375     }
   8376     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   8377     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   8378     extra->eType = OMX_ExtraDataNone;
   8379     extra->nDataSize = 0;
   8380     extra->data[0] = 0;
   8381 
   8382     print_debug_extradata(extra);
   8383 }
   8384 
   8385 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   8386 {
   8387     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8388     if (index >= drv_ctx.ip_buf.actualcount) {
   8389         DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
   8390         return OMX_ErrorInsufficientResources;
   8391     }
   8392     if (m_desc_buffer_ptr == NULL) {
   8393         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   8394                     calloc( (sizeof(desc_buffer_hdr)),
   8395                             drv_ctx.ip_buf.actualcount);
   8396         if (m_desc_buffer_ptr == NULL) {
   8397             DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
   8398             return OMX_ErrorInsufficientResources;
   8399         }
   8400     }
   8401 
   8402     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   8403     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   8404         DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
   8405         return OMX_ErrorInsufficientResources;
   8406     }
   8407 
   8408     return eRet;
   8409 }
   8410 
   8411 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   8412 {
   8413     DEBUG_PRINT_LOW("Inserting address offset (%lu) at idx (%lu)", address_offset,m_demux_entries);
   8414     if (m_demux_entries < 8192) {
   8415         m_demux_offsets[m_demux_entries++] = address_offset;
   8416     }
   8417     return;
   8418 }
   8419 
   8420 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   8421 {
   8422     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   8423     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   8424     OMX_U32 index = 0;
   8425 
   8426     m_demux_entries = 0;
   8427 
   8428     while (index < bytes_to_parse) {
   8429         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   8430                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   8431                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   8432                  (buf[index+2] == 0x01)) ) {
   8433             //Found start code, insert address offset
   8434             insert_demux_addr_offset(index);
   8435             if (buf[index+2] == 0x01) // 3 byte start code
   8436                 index += 3;
   8437             else                      //4 byte start code
   8438                 index += 4;
   8439         } else
   8440             index++;
   8441     }
   8442     DEBUG_PRINT_LOW("Extracted (%lu) demux entry offsets",m_demux_entries);
   8443     return;
   8444 }
   8445 
   8446 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   8447 {
   8448     //fix this, handle 3 byte start code, vc1 terminator entry
   8449     OMX_U8 *p_demux_data = NULL;
   8450     OMX_U32 desc_data = 0;
   8451     OMX_U32 start_addr = 0;
   8452     OMX_U32 nal_size = 0;
   8453     OMX_U32 suffix_byte = 0;
   8454     OMX_U32 demux_index = 0;
   8455     OMX_U32 buffer_index = 0;
   8456 
   8457     if (m_desc_buffer_ptr == NULL) {
   8458         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   8459         return OMX_ErrorBadParameter;
   8460     }
   8461 
   8462     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   8463     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   8464         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%lu)", buffer_index);
   8465         return OMX_ErrorBadParameter;
   8466     }
   8467 
   8468     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   8469 
   8470     if ( ((OMX_U8*)p_demux_data == NULL) ||
   8471             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   8472         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   8473         return OMX_ErrorBadParameter;
   8474     } else {
   8475         for (; demux_index < m_demux_entries; demux_index++) {
   8476             desc_data = 0;
   8477             start_addr = m_demux_offsets[demux_index];
   8478             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   8479                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   8480             } else {
   8481                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   8482             }
   8483             if (demux_index < (m_demux_entries - 1)) {
   8484                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   8485             } else {
   8486                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   8487             }
   8488             DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%lx),nal_size(%lu),demux_index(%lu)",
   8489                     (void *)start_addr,
   8490                     suffix_byte,
   8491                     nal_size,
   8492                     demux_index);
   8493             desc_data = (start_addr >> 3) << 1;
   8494             desc_data |= (start_addr & 7) << 21;
   8495             desc_data |= suffix_byte << 24;
   8496 
   8497             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   8498             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   8499             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   8500             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   8501 
   8502             p_demux_data += 16;
   8503         }
   8504         if (codec_type_parse == CODEC_TYPE_VC1) {
   8505             DEBUG_PRINT_LOW("VC1 terminator entry");
   8506             desc_data = 0;
   8507             desc_data = 0x82 << 24;
   8508             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   8509             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   8510             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   8511             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   8512             p_demux_data += 16;
   8513             m_demux_entries++;
   8514         }
   8515         //Add zero word to indicate end of descriptors
   8516         memset(p_demux_data, 0, sizeof(OMX_U32));
   8517 
   8518         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   8519         DEBUG_PRINT_LOW("desc table data size=%lu", m_desc_buffer_ptr[buffer_index].desc_data_size);
   8520     }
   8521     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   8522     m_demux_entries = 0;
   8523     DEBUG_PRINT_LOW("Demux table complete!");
   8524     return OMX_ErrorNone;
   8525 }
   8526 
   8527 OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
   8528 {
   8529     OMX_ERRORTYPE err = OMX_ErrorNone;
   8530     iDivXDrmDecrypt = DivXDrmDecrypt::Create();
   8531     if (iDivXDrmDecrypt) {
   8532         OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
   8533         if (err!=OMX_ErrorNone) {
   8534             DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
   8535             delete iDivXDrmDecrypt;
   8536             iDivXDrmDecrypt = NULL;
   8537         }
   8538     } else {
   8539         DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
   8540         err = OMX_ErrorUndefined;
   8541     }
   8542     return err;
   8543 }
   8544 
   8545 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   8546 {
   8547     enabled = false;
   8548     omx = NULL;
   8549     init_members();
   8550     ColorFormat = OMX_COLOR_FormatMax;
   8551 }
   8552 
   8553 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   8554 {
   8555     omx = reinterpret_cast<omx_vdec*>(client);
   8556 }
   8557 
   8558 void omx_vdec::allocate_color_convert_buf::init_members()
   8559 {
   8560     allocated_count = 0;
   8561     buffer_size_req = 0;
   8562     buffer_alignment_req = 0;
   8563     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   8564     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   8565     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   8566     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   8567 #ifdef USE_ION
   8568     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   8569 #endif
   8570     for (int i = 0; i < MAX_COUNT; i++)
   8571         pmem_fd[i] = -1;
   8572 }
   8573 
   8574 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   8575 {
   8576     c2d.destroy();
   8577 }
   8578 
   8579 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   8580 {
   8581     bool status = true;
   8582     unsigned int src_size = 0, destination_size = 0;
   8583     OMX_COLOR_FORMATTYPE drv_color_format;
   8584     if (!omx) {
   8585         DEBUG_PRINT_ERROR("\n Invalid client in color convert");
   8586         return false;
   8587     }
   8588     if (!enabled) {
   8589         DEBUG_PRINT_HIGH("\n No color conversion required");
   8590         return status;
   8591     }
   8592     pthread_mutex_lock(&omx->c_lock);
   8593     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   8594             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   8595         DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
   8596         status = false;
   8597         goto fail_update_buf_req;
   8598     }
   8599     c2d.close();
   8600     status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
   8601             omx->drv_ctx.video_resolution.frame_width,
   8602             NV12_128m,YCbCr420P);
   8603     if (status) {
   8604         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   8605         if (status)
   8606             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   8607     }
   8608     if (status) {
   8609         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   8610                 !destination_size) {
   8611             DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
   8612                     "driver size %d destination size %d",
   8613                     src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
   8614             status = false;
   8615             c2d.close();
   8616             buffer_size_req = 0;
   8617         } else {
   8618             buffer_size_req = destination_size;
   8619             if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
   8620                 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
   8621             if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   8622                 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   8623         }
   8624     }
   8625 fail_update_buf_req:
   8626     pthread_mutex_unlock(&omx->c_lock);
   8627     return status;
   8628 }
   8629 
   8630 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   8631         OMX_COLOR_FORMATTYPE dest_color_format)
   8632 {
   8633     bool status = true;
   8634     OMX_COLOR_FORMATTYPE drv_color_format;
   8635     if (!omx) {
   8636         DEBUG_PRINT_ERROR("\n Invalid client in color convert");
   8637         return false;
   8638     }
   8639     pthread_mutex_lock(&omx->c_lock);
   8640     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   8641         drv_color_format = (OMX_COLOR_FORMATTYPE)
   8642             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   8643     else {
   8644         DEBUG_PRINT_ERROR("\n Incorrect color format");
   8645         status = false;
   8646     }
   8647     if (status && (drv_color_format != dest_color_format)) {
   8648         DEBUG_PRINT_LOW("Enabling C2D\n");
   8649         if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
   8650             DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
   8651             status = false;
   8652         } else {
   8653             ColorFormat = OMX_COLOR_FormatYUV420Planar;
   8654             if (enabled)
   8655                 c2d.destroy();
   8656             enabled = false;
   8657             if (!c2d.init()) {
   8658                 DEBUG_PRINT_ERROR("\n open failed for c2d");
   8659                 status = false;
   8660             } else
   8661                 enabled = true;
   8662         }
   8663     } else {
   8664         if (enabled)
   8665             c2d.destroy();
   8666         enabled = false;
   8667     }
   8668     pthread_mutex_unlock(&omx->c_lock);
   8669     return status;
   8670 }
   8671 
   8672 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   8673 {
   8674     if (!omx) {
   8675         DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
   8676         return NULL;
   8677     }
   8678     if (!enabled)
   8679         return omx->m_out_mem_ptr;
   8680     return m_out_mem_ptr_client;
   8681 }
   8682 
   8683     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   8684 (OMX_BUFFERHEADERTYPE *bufadd)
   8685 {
   8686     if (!omx) {
   8687         DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
   8688         return NULL;
   8689     }
   8690     if (!enabled)
   8691         return bufadd;
   8692 
   8693     unsigned index = 0;
   8694     index = bufadd - omx->m_out_mem_ptr;
   8695     if (index < omx->drv_ctx.op_buf.actualcount) {
   8696         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   8697         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   8698         bool status;
   8699         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   8700             pthread_mutex_lock(&omx->c_lock);
   8701             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   8702                     omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
   8703                     pmem_baseaddress[index], pmem_baseaddress[index]);
   8704             pthread_mutex_unlock(&omx->c_lock);
   8705             m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
   8706             if (!status) {
   8707                 DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
   8708                 m_out_mem_ptr_client[index].nFilledLen = 0;
   8709                 return &m_out_mem_ptr_client[index];
   8710             }
   8711         } else
   8712             m_out_mem_ptr_client[index].nFilledLen = 0;
   8713         return &m_out_mem_ptr_client[index];
   8714     }
   8715     DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
   8716     return NULL;
   8717 }
   8718 
   8719     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   8720 (OMX_BUFFERHEADERTYPE *bufadd)
   8721 {
   8722     if (!omx) {
   8723         DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
   8724         return NULL;
   8725     }
   8726     if (!enabled)
   8727         return bufadd;
   8728     unsigned index = 0;
   8729     index = bufadd - m_out_mem_ptr_client;
   8730     if (index < omx->drv_ctx.op_buf.actualcount) {
   8731         return &omx->m_out_mem_ptr[index];
   8732     }
   8733     DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
   8734     return NULL;
   8735 }
   8736     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   8737 (unsigned int &buffer_size)
   8738 {
   8739     bool status = true;
   8740     pthread_mutex_lock(&omx->c_lock);
   8741     if (!enabled)
   8742         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   8743     else {
   8744         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   8745             DEBUG_PRINT_ERROR("\n Get buffer size failed");
   8746             status = false;
   8747             goto fail_get_buffer_size;
   8748         }
   8749     }
   8750     if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
   8751         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   8752     if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   8753         buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   8754 fail_get_buffer_size:
   8755     pthread_mutex_unlock(&omx->c_lock);
   8756     return status;
   8757 }
   8758 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   8759         OMX_BUFFERHEADERTYPE *bufhdr)
   8760 {
   8761     unsigned int index = 0;
   8762 
   8763     if (!enabled)
   8764         return omx->free_output_buffer(bufhdr);
   8765     if (enabled && omx->is_component_secure())
   8766         return OMX_ErrorNone;
   8767     if (!allocated_count || !bufhdr) {
   8768         DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
   8769         return OMX_ErrorBadParameter;
   8770     }
   8771     index = bufhdr - m_out_mem_ptr_client;
   8772     if (index >= omx->drv_ctx.op_buf.actualcount) {
   8773         DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
   8774         return OMX_ErrorBadParameter;
   8775     }
   8776     if (pmem_fd[index] > 0) {
   8777         munmap(pmem_baseaddress[index], buffer_size_req);
   8778         close(pmem_fd[index]);
   8779     }
   8780     pmem_fd[index] = -1;
   8781 #ifdef USE_ION
   8782     omx->free_ion_memory(&op_buf_ion_info[index]);
   8783 #endif
   8784     m_heap_ptr[index].video_heap_ptr = NULL;
   8785     if (allocated_count > 0)
   8786         allocated_count--;
   8787     else
   8788         allocated_count = 0;
   8789     if (!allocated_count) {
   8790         pthread_mutex_lock(&omx->c_lock);
   8791         c2d.close();
   8792         init_members();
   8793         pthread_mutex_unlock(&omx->c_lock);
   8794     }
   8795     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   8796 }
   8797 
   8798 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   8799         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   8800 {
   8801     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8802     if (!enabled) {
   8803         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   8804         return eRet;
   8805     }
   8806     if (enabled && omx->is_component_secure()) {
   8807         DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
   8808                 omx->is_component_secure());
   8809         return OMX_ErrorUnsupportedSetting;
   8810     }
   8811     if (!bufferHdr || bytes > buffer_size_req) {
   8812         DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
   8813         DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %lu",
   8814                 buffer_size_req,bytes);
   8815         return OMX_ErrorBadParameter;
   8816     }
   8817     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   8818         DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
   8819         return OMX_ErrorInsufficientResources;
   8820     }
   8821     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   8822     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   8823             port,appData,omx->drv_ctx.op_buf.buffer_size);
   8824     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   8825         DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
   8826         return eRet;
   8827     }
   8828     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   8829             omx->drv_ctx.op_buf.actualcount) {
   8830         DEBUG_PRINT_ERROR("\n Invalid header index %d",
   8831                 (temp_bufferHdr - omx->m_out_mem_ptr));
   8832         return OMX_ErrorUndefined;
   8833     }
   8834     unsigned int i = allocated_count;
   8835 #ifdef USE_ION
   8836     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   8837             buffer_size_req,buffer_alignment_req,
   8838             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   8839             0);
   8840     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   8841     if (op_buf_ion_info[i].ion_device_fd < 0) {
   8842         DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
   8843         return OMX_ErrorInsufficientResources;
   8844     }
   8845     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   8846             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   8847 
   8848     if (pmem_baseaddress[i] == MAP_FAILED) {
   8849         DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
   8850         close(pmem_fd[i]);
   8851         omx->free_ion_memory(&op_buf_ion_info[i]);
   8852         return OMX_ErrorInsufficientResources;
   8853     }
   8854     m_heap_ptr[i].video_heap_ptr = new VideoHeap (
   8855             op_buf_ion_info[i].ion_device_fd,buffer_size_req,
   8856             pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
   8857 #endif
   8858     m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
   8859     m_pmem_info_client[i].offset = 0;
   8860     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   8861     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   8862     m_platform_list_client[i].nEntries = 1;
   8863     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   8864     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   8865     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   8866     m_out_mem_ptr_client[i].nFilledLen = 0;
   8867     m_out_mem_ptr_client[i].nFlags = 0;
   8868     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   8869     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   8870     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   8871     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   8872     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   8873     m_out_mem_ptr_client[i].pAppPrivate = appData;
   8874     *bufferHdr = &m_out_mem_ptr_client[i];
   8875     DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
   8876     allocated_count++;
   8877     return eRet;
   8878 }
   8879 
   8880 bool omx_vdec::is_component_secure()
   8881 {
   8882     return secure_mode;
   8883 }
   8884 
   8885 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   8886 {
   8887     bool status = true;
   8888     if (!enabled) {
   8889         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   8890             dest_color_format =  (OMX_COLOR_FORMATTYPE)
   8891                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   8892         else
   8893             status = false;
   8894     } else {
   8895         if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   8896             status = false;
   8897         } else
   8898             dest_color_format = OMX_COLOR_FormatYUV420Planar;
   8899     }
   8900     return status;
   8901 }
   8902 
   8903 void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
   8904 {
   8905     int i = 0;
   8906     bool buf_present = false;
   8907     pthread_mutex_lock(&m_lock);
   8908     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   8909         //check the buffer fd, offset, uv addr with list contents
   8910         //If present increment reference.
   8911         if ((out_dynamic_list[i].fd == fd) &&
   8912             (out_dynamic_list[i].offset == offset)) {
   8913                out_dynamic_list[i].ref_count++;
   8914                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %d ref_count = %d\n",
   8915                      out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
   8916                buf_present = true;
   8917                break;
   8918         }
   8919     }
   8920     if (!buf_present) {
   8921         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   8922             //search for a entry to insert details of the new buffer
   8923             if (out_dynamic_list[i].dup_fd == 0) {
   8924                 out_dynamic_list[i].fd = fd;
   8925                 out_dynamic_list[i].offset = offset;
   8926                 out_dynamic_list[i].dup_fd = dup(fd);
   8927                 out_dynamic_list[i].ref_count++;
   8928                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %d ref_count = %d\n",
   8929                      out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
   8930                 break;
   8931             }
   8932         }
   8933     }
   8934    pthread_mutex_unlock(&m_lock);
   8935 }
   8936 
   8937 void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
   8938 {
   8939     int i = 0;
   8940     pthread_mutex_lock(&m_lock);
   8941     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   8942         //check the buffer fd, offset, uv addr with list contents
   8943         //If present decrement reference.
   8944         if ((out_dynamic_list[i].fd == fd) &&
   8945             (out_dynamic_list[i].offset == offset)) {
   8946             out_dynamic_list[i].ref_count--;
   8947             if (out_dynamic_list[i].ref_count == 0) {
   8948                 close(out_dynamic_list[i].dup_fd);
   8949                 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %d ref_count = %d\n",
   8950                      out_dynamic_list[i].fd, out_dynamic_list[i].ref_count);
   8951                 out_dynamic_list[i].dup_fd = 0;
   8952                 out_dynamic_list[i].fd = 0;
   8953                 out_dynamic_list[i].offset = 0;
   8954             }
   8955             break;
   8956         }
   8957     }
   8958     if (i  >= drv_ctx.op_buf.actualcount) {
   8959         DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list\n");
   8960     }
   8961     pthread_mutex_unlock(&m_lock);
   8962 }
   8963 
   8964 void omx_vdec::send_codec_config() {
   8965     if (codec_config_flag) {
   8966         unsigned      p1 = 0; // Parameter - 1
   8967         unsigned      p2 = 0; // Parameter - 2
   8968         unsigned      ident = 0;
   8969         pthread_mutex_lock(&m_lock);
   8970         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   8971         while (m_etb_q.m_size) {
   8972             m_etb_q.pop_entry(&p1,&p2,&ident);
   8973             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   8974                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   8975                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   8976                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   8977                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   8978                         omx_report_error();
   8979                     }
   8980                 } else {
   8981                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   8982                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   8983                 }
   8984             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   8985                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   8986                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   8987                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   8988                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   8989                         omx_report_error ();
   8990                     }
   8991                 } else {
   8992                     pending_input_buffers++;
   8993                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   8994                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   8995                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   8996                 }
   8997             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   8998                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   8999                         (OMX_BUFFERHEADERTYPE *)p1);
   9000                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   9001             }
   9002         }
   9003         pthread_mutex_unlock(&m_lock);
   9004     }
   9005 }
   9006