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