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