Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2016, 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   This module contains the implementation of the OpenMAX core & component.
     34 
     35 *//*========================================================================*/
     36 
     37 //////////////////////////////////////////////////////////////////////////////
     38 //                             Include Files
     39 //////////////////////////////////////////////////////////////////////////////
     40 
     41 #define __STDC_FORMAT_MACROS
     42 #include <inttypes.h>
     43 
     44 #include <string.h>
     45 #include <pthread.h>
     46 #include <sys/prctl.h>
     47 #include <stdlib.h>
     48 #include <unistd.h>
     49 #include <errno.h>
     50 #include "omx_vdec.h"
     51 #include <fcntl.h>
     52 #include <limits.h>
     53 #include <stdlib.h>
     54 #include <media/hardware/HardwareAPI.h>
     55 #include <media/msm_media_info.h>
     56 #include <sys/eventfd.h>
     57 
     58 #ifndef _ANDROID_
     59 #include <sys/ioctl.h>
     60 #include <sys/mman.h>
     61 #endif //_ANDROID_
     62 
     63 #ifdef _ANDROID_
     64 #include <cutils/properties.h>
     65 #undef USE_EGL_IMAGE_GPU
     66 #endif
     67 
     68 #include <qdMetaData.h>
     69 
     70 #ifdef ANDROID_JELLYBEAN_MR2
     71 #include "QComOMXMetadata.h"
     72 #endif
     73 
     74 #ifdef USE_EGL_IMAGE_GPU
     75 #include <EGL/egl.h>
     76 #include <EGL/eglQCOM.h>
     77 #define EGL_BUFFER_HANDLE 0x4F00
     78 #define EGL_BUFFER_OFFSET 0x4F01
     79 #endif
     80 
     81 #define BUFFER_LOG_LOC "/data/misc/media"
     82 
     83 #ifdef OUTPUT_EXTRADATA_LOG
     84 FILE *outputExtradataFile;
     85 char output_extradata_filename [] = "/data/misc/media/extradata";
     86 #endif
     87 
     88 #define DEFAULT_FPS 30
     89 #define MAX_SUPPORTED_FPS 120
     90 #define DEFAULT_WIDTH_ALIGNMENT 128
     91 #define DEFAULT_HEIGHT_ALIGNMENT 32
     92 
     93 #define VC1_SP_MP_START_CODE        0xC5000000
     94 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     95 #define VC1_AP_SEQ_START_CODE       0x0F010000
     96 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
     97 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
     98 #define VC1_SIMPLE_PROFILE          0
     99 #define VC1_MAIN_PROFILE            1
    100 #define VC1_ADVANCE_PROFILE         3
    101 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
    102 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
    103 #define VC1_STRUCT_C_LEN            4
    104 #define VC1_STRUCT_C_POS            8
    105 #define VC1_STRUCT_A_POS            12
    106 #define VC1_STRUCT_B_POS            24
    107 #define VC1_SEQ_LAYER_SIZE          36
    108 #define POLL_TIMEOUT 0x7fffffff
    109 
    110 #define MEM_DEVICE "/dev/ion"
    111 
    112 #ifdef _ANDROID_
    113 extern "C" {
    114 #include<utils/Log.h>
    115 }
    116 #endif//_ANDROID_
    117 
    118 #define SZ_4K 0x1000
    119 #define SZ_1M 0x100000
    120 
    121 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    122 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    123 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
    124 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
    125 
    126 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_DISPLAY_INFO_EXTRADATA)
    127 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
    128 
    129 #ifndef ION_FLAG_CP_BITSTREAM
    130 #define ION_FLAG_CP_BITSTREAM 0
    131 #endif
    132 
    133 #ifndef ION_FLAG_CP_PIXEL
    134 #define ION_FLAG_CP_PIXEL 0
    135 #endif
    136 
    137 #ifdef MASTER_SIDE_CP
    138 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
    139 #define SECURE_ALIGN SZ_4K
    140 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
    141 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
    142 #else //SLAVE_SIDE_CP
    143 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    144 #define SECURE_ALIGN SZ_1M
    145 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
    146 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
    147 #endif
    148 
    149 static OMX_U32 maxSmoothStreamingWidth = 1920;
    150 static OMX_U32 maxSmoothStreamingHeight = 1088;
    151 
    152 void* async_message_thread (void *input)
    153 {
    154     OMX_BUFFERHEADERTYPE *buffer;
    155     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    156     struct pollfd pfds[2];
    157     struct v4l2_buffer v4l2_buf;
    158     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    159     struct v4l2_event dqevent;
    160     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
    161     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    162     pfds[1].events = POLLIN | POLLERR;
    163     pfds[0].fd = omx->drv_ctx.video_driver_fd;
    164     pfds[1].fd = omx->m_poll_efd;
    165     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    166     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
    167     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
    168     while (!omx->async_thread_force_stop) {
    169         rc = poll(pfds, 2, POLL_TIMEOUT);
    170         if (!rc) {
    171             DEBUG_PRINT_ERROR("Poll timedout");
    172             break;
    173         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
    174             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
    175             break;
    176         }
    177         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
    178             DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
    179             break;
    180         }
    181         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
    182             struct vdec_msginfo vdec_msg;
    183             memset(&vdec_msg, 0, sizeof(vdec_msg));
    184             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    185             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    186             v4l2_buf.length = omx->drv_ctx.num_planes;
    187             v4l2_buf.m.planes = plane;
    188             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    189                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    190                 vdec_msg.status_code=VDEC_S_SUCCESS;
    191                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    192                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
    193                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
    194                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    195                     (uint64_t)v4l2_buf.timestamp.tv_usec;
    196                 if (vdec_msg.msgdata.output_frame.len) {
    197                     vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
    198                     vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
    199                     vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
    200                     vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
    201                     vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
    202                     vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
    203                 }
    204                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    205                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    206                     break;
    207                 }
    208             }
    209         }
    210         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
    211             struct vdec_msginfo vdec_msg;
    212             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    213             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    214             v4l2_buf.length = 1;
    215             v4l2_buf.m.planes = plane;
    216             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    217                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
    218                 vdec_msg.status_code=VDEC_S_SUCCESS;
    219                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    220                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    221                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    222                     break;
    223                 }
    224             }
    225         }
    226         if (pfds[0].revents & POLLPRI) {
    227             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
    228             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
    229                 struct vdec_msginfo vdec_msg;
    230                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    231 
    232                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    233                 vdec_msg.status_code=VDEC_S_SUCCESS;
    234                 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
    235                 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
    236                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
    237                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    238                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    239                     break;
    240                 }
    241             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT ) {
    242                 struct vdec_msginfo vdec_msg;
    243                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    244                 vdec_msg.status_code=VDEC_S_SUCCESS;
    245                 omx->dpb_bit_depth = dqevent.u.data[0];
    246                 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", dqevent.u.data[0]);
    247                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    248                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    249                     break;
    250                 }
    251             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    252                 struct vdec_msginfo vdec_msg;
    253                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
    254                 vdec_msg.status_code=VDEC_S_SUCCESS;
    255                 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
    256                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    257                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    258                     break;
    259                 }
    260                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
    261                 vdec_msg.status_code=VDEC_S_SUCCESS;
    262                 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
    263                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    264                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    265                     break;
    266                 }
    267             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
    268                 struct vdec_msginfo vdec_msg;
    269                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
    270                 vdec_msg.status_code=VDEC_S_SUCCESS;
    271                 DEBUG_PRINT_ERROR("HW Overload received");
    272                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    273                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    274                     break;
    275                 }
    276             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
    277                 struct vdec_msginfo vdec_msg;
    278                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
    279                 vdec_msg.status_code=VDEC_S_SUCCESS;
    280                 DEBUG_PRINT_ERROR("HW Unsupported received");
    281                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    282                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    283                     break;
    284                 }
    285             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    286                 struct vdec_msginfo vdec_msg;
    287                 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
    288                 vdec_msg.status_code = VDEC_S_SUCCESS;
    289                 DEBUG_PRINT_HIGH("SYS Error Recieved");
    290                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    291                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    292                     break;
    293                 }
    294             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
    295                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    296 
    297                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
    298             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
    299                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    300                 struct vdec_msginfo vdec_msg;
    301 
    302                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
    303 
    304                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    305                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    306                 v4l2_buf.length = omx->drv_ctx.num_planes;
    307                 v4l2_buf.m.planes = plane;
    308                 v4l2_buf.index = ptr[5];
    309                 v4l2_buf.flags = 0;
    310 
    311                 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    312                 vdec_msg.status_code = VDEC_S_SUCCESS;
    313                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
    314                 vdec_msg.msgdata.output_frame.len = 0;
    315                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
    316                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
    317                     (uint64_t)ptr[4];
    318                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    319                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
    320                     break;
    321                 }
    322             } else {
    323                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
    324                 continue;
    325             }
    326         }
    327     }
    328     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
    329     return NULL;
    330 }
    331 
    332 void* message_thread(void *input)
    333 {
    334     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    335     unsigned char id;
    336     int n;
    337 
    338     fd_set readFds;
    339     int res = 0;
    340     struct timeval tv;
    341 
    342     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
    343     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
    344     while (!omx->message_thread_stop) {
    345 
    346         tv.tv_sec = 2;
    347         tv.tv_usec = 0;
    348 
    349         FD_ZERO(&readFds);
    350         FD_SET(omx->m_pipe_in, &readFds);
    351 
    352         res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
    353         if (res < 0) {
    354             DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
    355             continue;
    356         } else if (res == 0 /*timeout*/ || omx->message_thread_stop) {
    357             continue;
    358         }
    359 
    360         n = read(omx->m_pipe_in, &id, 1);
    361 
    362         if (0 == n) {
    363             break;
    364         }
    365 
    366         if (1 == n) {
    367             omx->process_event_cb(omx, id);
    368         }
    369 
    370         if ((n < 0) && (errno != EINTR)) {
    371             DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    372             break;
    373         }
    374     }
    375     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
    376     return 0;
    377 }
    378 
    379 void post_message(omx_vdec *omx, unsigned char id)
    380 {
    381     int ret_value;
    382     DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
    383     ret_value = write(omx->m_pipe_out, &id, 1);
    384     if (ret_value <= 0) {
    385         DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
    386     } else {
    387         DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    388     }
    389 }
    390 
    391 // omx_cmd_queue destructor
    392 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    393 {
    394     // Nothing to do
    395 }
    396 
    397 // omx cmd queue constructor
    398 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    399 {
    400     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    401 }
    402 
    403 // omx cmd queue insert
    404 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
    405 {
    406     bool ret = true;
    407     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    408         m_q[m_write].id       = id;
    409         m_q[m_write].param1   = p1;
    410         m_q[m_write].param2   = p2;
    411         m_write++;
    412         m_size ++;
    413         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    414             m_write = 0;
    415         }
    416     } else {
    417         ret = false;
    418         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
    419     }
    420     return ret;
    421 }
    422 
    423 // omx cmd queue pop
    424 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
    425 {
    426     bool ret = true;
    427     if (m_size > 0) {
    428         *id = m_q[m_read].id;
    429         *p1 = m_q[m_read].param1;
    430         *p2 = m_q[m_read].param2;
    431         // Move the read pointer ahead
    432         ++m_read;
    433         --m_size;
    434         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    435             m_read = 0;
    436         }
    437     } else {
    438         ret = false;
    439     }
    440     return ret;
    441 }
    442 
    443 // Retrieve the first mesg type in the queue
    444 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    445 {
    446     return m_q[m_read].id;
    447 }
    448 
    449 #ifdef _ANDROID_
    450 omx_vdec::ts_arr_list::ts_arr_list()
    451 {
    452     //initialize timestamps array
    453     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    454 }
    455 omx_vdec::ts_arr_list::~ts_arr_list()
    456 {
    457     //free m_ts_arr_list?
    458 }
    459 
    460 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
    461 {
    462     bool ret = true;
    463     bool duplicate_ts = false;
    464     int idx = 0;
    465 
    466     //insert at the first available empty location
    467     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    468         if (!m_ts_arr_list[idx].valid) {
    469             //found invalid or empty entry, save timestamp
    470             m_ts_arr_list[idx].valid = true;
    471             m_ts_arr_list[idx].timestamp = ts;
    472             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    473                     ts, idx);
    474             break;
    475         }
    476     }
    477 
    478     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
    479         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    480         ret = false;
    481     }
    482     return ret;
    483 }
    484 
    485 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    486 {
    487     bool ret = true;
    488     int min_idx = -1;
    489     OMX_TICKS min_ts = 0;
    490     int idx = 0;
    491 
    492     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    493 
    494         if (m_ts_arr_list[idx].valid) {
    495             //found valid entry, save index
    496             if (min_idx < 0) {
    497                 //first valid entry
    498                 min_ts = m_ts_arr_list[idx].timestamp;
    499                 min_idx = idx;
    500             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
    501                 min_ts = m_ts_arr_list[idx].timestamp;
    502                 min_idx = idx;
    503             }
    504         }
    505 
    506     }
    507 
    508     if (min_idx < 0) {
    509         //no valid entries found
    510         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    511         ts = 0;
    512         ret = false;
    513     } else {
    514         ts = m_ts_arr_list[min_idx].timestamp;
    515         m_ts_arr_list[min_idx].valid = false;
    516         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    517                 ts, min_idx);
    518     }
    519 
    520     return ret;
    521 
    522 }
    523 
    524 
    525 bool omx_vdec::ts_arr_list::reset_ts_list()
    526 {
    527     bool ret = true;
    528     int idx = 0;
    529 
    530     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    531     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    532         m_ts_arr_list[idx].valid = false;
    533     }
    534     return ret;
    535 }
    536 #endif
    537 
    538 // factory function executed by the core to create instances
    539 void *get_omx_component_factory_fn(void)
    540 {
    541     return (new omx_vdec);
    542 }
    543 
    544 #ifdef _ANDROID_
    545 #ifdef USE_ION
    546 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
    547         ion_user_handle_t handle, int ionMapfd)
    548 {
    549     (void) devicefd;
    550     (void) size;
    551     (void) base;
    552     (void) handle;
    553     (void) ionMapfd;
    554     //    ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
    555 }
    556 #else
    557 VideoHeap::VideoHeap(int fd, size_t size, void* base)
    558 {
    559     // dup file descriptor, map once, use pmem
    560     init(dup(fd), base, size, 0 , MEM_DEVICE);
    561 }
    562 #endif
    563 #endif // _ANDROID_
    564 /* ======================================================================
    565    FUNCTION
    566    omx_vdec::omx_vdec
    567 
    568    DESCRIPTION
    569    Constructor
    570 
    571    PARAMETERS
    572    None
    573 
    574    RETURN VALUE
    575    None.
    576    ========================================================================== */
    577 omx_vdec::omx_vdec(): m_error_propogated(false),
    578     m_state(OMX_StateInvalid),
    579     m_app_data(NULL),
    580     m_inp_mem_ptr(NULL),
    581     m_out_mem_ptr(NULL),
    582     input_flush_progress (false),
    583     output_flush_progress (false),
    584     input_use_buffer (false),
    585     output_use_buffer (false),
    586     ouput_egl_buffers(false),
    587     m_use_output_pmem(OMX_FALSE),
    588     m_out_mem_region_smi(OMX_FALSE),
    589     m_out_pvt_entry_pmem(OMX_FALSE),
    590     pending_input_buffers(0),
    591     pending_output_buffers(0),
    592     m_out_bm_count(0),
    593     m_inp_bm_count(0),
    594     m_inp_bPopulated(OMX_FALSE),
    595     m_out_bPopulated(OMX_FALSE),
    596     m_flags(0),
    597 #ifdef _ANDROID_
    598     m_heap_ptr(NULL),
    599 #endif
    600     m_inp_bEnabled(OMX_TRUE),
    601     m_out_bEnabled(OMX_TRUE),
    602     m_in_alloc_cnt(0),
    603     m_platform_list(NULL),
    604     m_platform_entry(NULL),
    605     m_pmem_info(NULL),
    606     h264_parser(NULL),
    607     arbitrary_bytes (true),
    608     psource_frame (NULL),
    609     pdest_frame (NULL),
    610     m_inp_heap_ptr (NULL),
    611     m_phdr_pmem_ptr(NULL),
    612     m_heap_inp_bm_count (0),
    613     codec_type_parse ((codec_type)0),
    614     first_frame_meta (true),
    615     frame_count (0),
    616     nal_count (0),
    617     nal_length(0),
    618     look_ahead_nal (false),
    619     first_frame(0),
    620     first_buffer(NULL),
    621     first_frame_size (0),
    622     m_device_file_ptr(NULL),
    623     m_vc1_profile((vc1_profile_type)0),
    624     h264_last_au_ts(LLONG_MAX),
    625     h264_last_au_flags(0),
    626     m_disp_hor_size(0),
    627     m_disp_vert_size(0),
    628     prev_ts(LLONG_MAX),
    629     prev_ts_actual(LLONG_MAX),
    630     rst_prev_ts(true),
    631     frm_int(0),
    632     in_reconfig(false),
    633     m_display_id(NULL),
    634     client_extradata(0),
    635     m_reject_avc_1080p_mp (0),
    636 #ifdef _ANDROID_
    637     m_enable_android_native_buffers(OMX_FALSE),
    638     m_use_android_native_buffers(OMX_FALSE),
    639 #endif
    640     m_desc_buffer_ptr(NULL),
    641     secure_mode(false),
    642     allocate_native_handle(false),
    643     m_other_extradata(NULL),
    644     m_profile(0),
    645     client_set_fps(false),
    646     m_last_rendered_TS(-1),
    647     m_queued_codec_config_count(0),
    648     current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
    649     secure_scaling_to_non_secure_opb(false),
    650     m_force_compressed_for_dpb(false)
    651 {
    652     m_pipe_in = -1;
    653     m_pipe_out = -1;
    654     m_poll_efd = -1;
    655     drv_ctx.video_driver_fd = -1;
    656     drv_ctx.extradata_info.ion.fd_ion_data.fd = -1;
    657     /* Assumption is that , to begin with , we have all the frames with decoder */
    658     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
    659     memset(&m_debug,0,sizeof(m_debug));
    660 #ifdef _ANDROID_
    661     char property_value[PROPERTY_VALUE_MAX] = {0};
    662     property_get("vidc.debug.level", property_value, "1");
    663     debug_level = atoi(property_value);
    664     property_value[0] = '\0';
    665 
    666     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
    667 
    668     property_get("vidc.dec.debug.perf", property_value, "0");
    669     perf_flag = atoi(property_value);
    670     if (perf_flag) {
    671         DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
    672         dec_time.start();
    673         proc_frms = latency = 0;
    674     }
    675     prev_n_filled_len = 0;
    676     property_value[0] = '\0';
    677     property_get("vidc.dec.debug.ts", property_value, "0");
    678     m_debug_timestamp = atoi(property_value);
    679     DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
    680     if (m_debug_timestamp) {
    681         time_stamp_dts.set_timestamp_reorder_mode(true);
    682         time_stamp_dts.enable_debug_print(true);
    683     }
    684 
    685     property_value[0] = '\0';
    686     property_get("vidc.dec.debug.concealedmb", property_value, "0");
    687     m_debug_concealedmb = atoi(property_value);
    688     DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
    689 
    690     property_value[0] = '\0';
    691     property_get("vidc.dec.profile.check", property_value, "0");
    692     m_reject_avc_1080p_mp = atoi(property_value);
    693     DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
    694 
    695     property_value[0] = '\0';
    696     property_get("vidc.dec.log.in", property_value, "0");
    697     m_debug.in_buffer_log = atoi(property_value);
    698 
    699     property_value[0] = '\0';
    700     property_get("vidc.dec.log.out", property_value, "0");
    701     m_debug.out_buffer_log = atoi(property_value);
    702     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    703 
    704     property_value[0] = '\0';
    705     property_get("vidc.dec.meta.log.out", property_value, "0");
    706     m_debug.out_meta_buffer_log = atoi(property_value);
    707     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    708 
    709     property_value[0] = '\0';
    710     property_get("vidc.log.loc", property_value, "");
    711     if (*property_value)
    712         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
    713 
    714     property_value[0] = '\0';
    715     property_get("vidc.dec.120fps.enabled", property_value, "0");
    716 
    717     //if this feature is not enabled then reset this value -ve
    718     if(atoi(property_value)) {
    719         DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
    720         m_last_rendered_TS = 0;
    721     }
    722 
    723     property_value[0] = '\0';
    724     property_get("vidc.dec.debug.dyn.disabled", property_value, "0");
    725     m_disable_dynamic_buf_mode = atoi(property_value);
    726     DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode);
    727 
    728 #ifdef _UBWC_
    729     property_value[0] = '\0';
    730     property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
    731     m_disable_ubwc_mode = atoi(property_value);
    732     DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
    733 #else
    734     m_disable_ubwc_mode = true;
    735 #endif
    736 #endif
    737     memset(&m_cmp,0,sizeof(m_cmp));
    738     memset(&m_cb,0,sizeof(m_cb));
    739     memset (&drv_ctx,0,sizeof(drv_ctx));
    740     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    741     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    742     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
    743     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
    744     memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
    745     memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
    746     m_demux_entries = 0;
    747     msg_thread_id = 0;
    748     async_thread_id = 0;
    749     msg_thread_created = false;
    750     async_thread_created = false;
    751     async_thread_force_stop = false;
    752     message_thread_stop = false;
    753 #ifdef _ANDROID_ICS_
    754     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    755 #endif
    756     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
    757 
    758     /* invalidate m_frame_pack_arrangement */
    759     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
    760     m_frame_pack_arrangement.cancel_flag = 1;
    761 
    762     drv_ctx.timestamp_adjust = false;
    763     m_vendor_config.pData = NULL;
    764     pthread_mutex_init(&m_lock, NULL);
    765     pthread_mutex_init(&c_lock, NULL);
    766     pthread_mutex_init(&buf_lock, NULL);
    767     sem_init(&m_cmd_lock,0,0);
    768     sem_init(&m_safe_flush, 0, 0);
    769     streaming[CAPTURE_PORT] =
    770         streaming[OUTPUT_PORT] = false;
    771 #ifdef _ANDROID_
    772     char extradata_value[PROPERTY_VALUE_MAX] = {0};
    773     property_get("vidc.dec.debug.extradata", extradata_value, "0");
    774     m_debug_extradata = atoi(extradata_value);
    775     DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
    776 #endif
    777     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    778     client_buffers.set_vdec_client(this);
    779     dynamic_buf_mode = false;
    780     out_dynamic_list = NULL;
    781     is_down_scalar_enabled = false;
    782     m_downscalar_width = 0;
    783     m_downscalar_height = 0;
    784     m_force_down_scalar = 0;
    785     m_reconfig_height = 0;
    786     m_reconfig_width = 0;
    787     m_smoothstreaming_mode = false;
    788     m_smoothstreaming_width = 0;
    789     m_smoothstreaming_height = 0;
    790     is_q6_platform = false;
    791     m_perf_control.send_hint_to_mpctl(true);
    792     m_input_pass_buffer_fd = false;
    793     m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    794     m_client_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    795     m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    796     m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    797     m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    798 
    799     m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    800     m_internal_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    801     m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    802     m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    803     m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    804     m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
    805 }
    806 
    807 static const int event_type[] = {
    808     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    809     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
    810     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
    811     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT,
    812     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
    813     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
    814     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
    815     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
    816     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
    817 };
    818 
    819 static OMX_ERRORTYPE subscribe_to_events(int fd)
    820 {
    821     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    822     struct v4l2_event_subscription sub;
    823     int array_sz = sizeof(event_type)/sizeof(int);
    824     int i,rc;
    825     if (fd < 0) {
    826         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    827         return OMX_ErrorBadParameter;
    828     }
    829 
    830     for (i = 0; i < array_sz; ++i) {
    831         memset(&sub, 0, sizeof(sub));
    832         sub.type = event_type[i];
    833         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    834         if (rc) {
    835             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    836             break;
    837         }
    838     }
    839     if (i < array_sz) {
    840         for (--i; i >=0 ; i--) {
    841             memset(&sub, 0, sizeof(sub));
    842             sub.type = event_type[i];
    843             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    844             if (rc)
    845                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    846         }
    847         eRet = OMX_ErrorNotImplemented;
    848     }
    849     return eRet;
    850 }
    851 
    852 
    853 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    854 {
    855     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    856     struct v4l2_event_subscription sub;
    857     int array_sz = sizeof(event_type)/sizeof(int);
    858     int i,rc;
    859     if (fd < 0) {
    860         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    861         return OMX_ErrorBadParameter;
    862     }
    863 
    864     for (i = 0; i < array_sz; ++i) {
    865         memset(&sub, 0, sizeof(sub));
    866         sub.type = event_type[i];
    867         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    868         if (rc) {
    869             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    870             break;
    871         }
    872     }
    873     return eRet;
    874 }
    875 
    876 /* ======================================================================
    877    FUNCTION
    878    omx_vdec::~omx_vdec
    879 
    880    DESCRIPTION
    881    Destructor
    882 
    883    PARAMETERS
    884    None
    885 
    886    RETURN VALUE
    887    None.
    888    ========================================================================== */
    889 omx_vdec::~omx_vdec()
    890 {
    891     m_pmem_info = NULL;
    892     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
    893     if (msg_thread_created) {
    894         DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
    895         message_thread_stop = true;
    896         post_message(this, OMX_COMPONENT_CLOSE_MSG);
    897         DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    898         pthread_join(msg_thread_id,NULL);
    899     }
    900     close(m_pipe_in);
    901     close(m_pipe_out);
    902     m_pipe_in = -1;
    903     m_pipe_out = -1;
    904     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    905     if(eventfd_write(m_poll_efd, 1)) {
    906          DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
    907          async_thread_force_stop = true;
    908     }
    909 
    910     if (async_thread_created)
    911         pthread_join(async_thread_id,NULL);
    912     unsubscribe_to_events(drv_ctx.video_driver_fd);
    913     close(m_poll_efd);
    914     close(drv_ctx.video_driver_fd);
    915     pthread_mutex_destroy(&m_lock);
    916     pthread_mutex_destroy(&c_lock);
    917     pthread_mutex_destroy(&buf_lock);
    918     sem_destroy(&m_cmd_lock);
    919     if (perf_flag) {
    920         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
    921         dec_time.end();
    922     }
    923     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
    924     m_perf_control.send_hint_to_mpctl(false);
    925 }
    926 
    927 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
    928 {
    929     struct v4l2_requestbuffers bufreq;
    930     int rc = 0;
    931     if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
    932         bufreq.memory = V4L2_MEMORY_USERPTR;
    933         bufreq.count = 0;
    934         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    935         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    936     } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
    937         bufreq.memory = V4L2_MEMORY_USERPTR;
    938         bufreq.count = 0;
    939         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    940         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    941     }
    942     return rc;
    943 }
    944 
    945 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format)
    946 {
    947     int rc = 0;
    948     struct v4l2_ext_control ctrl[2];
    949     struct v4l2_ext_controls controls;
    950 
    951     DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s",
    952          is_split_mode ? "split" : "combined",
    953          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc":
    954          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc":
    955          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb":
    956          "unknown",
    957          capture_capability == V4L2_PIX_FMT_NV12 ? "nv12":
    958          capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc":
    959          "unknown");
    960 
    961     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
    962     if (is_split_mode) {
    963         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
    964     } else {
    965         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
    966     }
    967 
    968     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
    969     ctrl[1].value = dpb_color_format;
    970 
    971     controls.count = 2;
    972     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
    973     controls.controls = ctrl;
    974 
    975     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
    976     if (rc) {
    977         DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
    978         return OMX_ErrorUnsupportedSetting;
    979     }
    980     return OMX_ErrorNone;
    981 }
    982 
    983 
    984 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool force_split_mode)
    985 {
    986     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    987 
    988     bool cpu_access = capture_capability != V4L2_PIX_FMT_NV12_UBWC;
    989 
    990     bool is_res_above_1080p = (drv_ctx.video_resolution.frame_width > 1920 &&
    991             drv_ctx.video_resolution.frame_height > 1088) ||
    992             (drv_ctx.video_resolution.frame_height > 1088 &&
    993              drv_ctx.video_resolution.frame_width > 1920);
    994 
    995     if (cpu_access) {
    996         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
    997             if ((m_force_compressed_for_dpb || is_res_above_1080p) &&
    998                 !force_split_mode) {
    999                 //split DPB-OPB
   1000                 //DPB -> UBWC , OPB -> Linear
   1001                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1002             } else if (force_split_mode) {
   1003                         //DPB -> Linear, OPB -> Linear
   1004                         eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1005             } else {
   1006                         //DPB-OPB combined linear
   1007                         eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1008            }
   1009         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1010             //split DPB-OPB
   1011             //DPB -> UBWC, OPB -> Linear
   1012             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1013         }
   1014     } else { //no cpu access
   1015         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1016             if (force_split_mode) {
   1017                 //split DPB-OPB
   1018                 //DPB -> UBWC, OPB -> UBWC
   1019                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1020             } else {
   1021                 //DPB-OPB combined UBWC
   1022                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1023             }
   1024         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1025             //split DPB-OPB
   1026             //DPB -> UBWC, OPB -> UBWC
   1027             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1028         }
   1029     }
   1030     if (eRet) {
   1031         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
   1032     }
   1033     return eRet;
   1034 }
   1035 
   1036 int omx_vdec::enable_downscalar()
   1037 {
   1038     int rc = 0;
   1039     struct v4l2_control control;
   1040     struct v4l2_format fmt;
   1041 
   1042     if (is_down_scalar_enabled) {
   1043         DEBUG_PRINT_LOW("%s: already enabled", __func__);
   1044         return 0;
   1045     }
   1046 
   1047     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
   1048     rc = decide_dpb_buffer_mode(true);
   1049     if (rc) {
   1050         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
   1051         return rc;
   1052     }
   1053     is_down_scalar_enabled = true;
   1054 
   1055     memset(&control, 0x0, sizeof(struct v4l2_control));
   1056     control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
   1057     control.value = 1;
   1058     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1059     if (rc) {
   1060         DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__);
   1061         return rc;
   1062     }
   1063 
   1064     return 0;
   1065 }
   1066 
   1067 int omx_vdec::disable_downscalar()
   1068 {
   1069     int rc = 0;
   1070     struct v4l2_control control;
   1071 
   1072     if (!is_down_scalar_enabled) {
   1073         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
   1074         return 0;
   1075     }
   1076 
   1077     rc = decide_dpb_buffer_mode(false);
   1078     if (rc < 0) {
   1079         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
   1080         return rc;
   1081     }
   1082     is_down_scalar_enabled = false;
   1083 
   1084     return rc;
   1085 }
   1086 
   1087 int omx_vdec::decide_downscalar()
   1088 {
   1089     int rc = 0;
   1090     struct v4l2_format fmt;
   1091     enum color_fmts color_format;
   1092 
   1093     if  (!m_downscalar_width || !m_downscalar_height) {
   1094         DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
   1095         return 0;
   1096     }
   1097 
   1098     if (m_force_down_scalar) {
   1099         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
   1100         return 0;
   1101     }
   1102 
   1103     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1104     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1105     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1106     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1107     if (rc < 0) {
   1108        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1109        return rc;
   1110     }
   1111 
   1112     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d", __func__,
   1113         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height);
   1114 
   1115     if (fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) {
   1116         rc = enable_downscalar();
   1117         if (rc < 0) {
   1118             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   1119             return rc;
   1120         }
   1121 
   1122         OMX_U32 width = m_downscalar_width > fmt.fmt.pix_mp.width ?
   1123                             fmt.fmt.pix_mp.width : m_downscalar_width;
   1124         OMX_U32 height = m_downscalar_height > fmt.fmt.pix_mp.height ?
   1125                             fmt.fmt.pix_mp.height : m_downscalar_height;
   1126         switch (capture_capability) {
   1127             case V4L2_PIX_FMT_NV12:
   1128                 color_format = COLOR_FMT_NV12;
   1129                 break;
   1130             case V4L2_PIX_FMT_NV12_UBWC:
   1131                 color_format = COLOR_FMT_NV12_UBWC;
   1132                 break;
   1133             case V4L2_PIX_FMT_NV12_TP10_UBWC:
   1134                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
   1135                 break;
   1136             default:
   1137                 DEBUG_PRINT_ERROR("Color format not recognized\n");
   1138                 rc = OMX_ErrorUndefined;
   1139                 return rc;
   1140         }
   1141 
   1142         rc = update_resolution(width, height,
   1143                 VENUS_Y_STRIDE(color_format, width), VENUS_Y_SCANLINES(color_format, height));
   1144         if (rc < 0) {
   1145             DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed \n", __func__, width, height);
   1146             return rc;
   1147         }
   1148     } else {
   1149 
   1150         rc = disable_downscalar();
   1151         if (rc < 0) {
   1152             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   1153             return rc;
   1154         }
   1155 
   1156         rc = update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
   1157                 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   1158         if (rc < 0) {
   1159             DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed\n", __func__, fmt.fmt.pix_mp.width,
   1160                 fmt.fmt.pix_mp.height);
   1161             return rc;
   1162         }
   1163     }
   1164 
   1165     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1166     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1167     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1168     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1169     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1170     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1171     if (rc) {
   1172         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1173         return rc;
   1174     }
   1175 
   1176     rc = get_buffer_req(&drv_ctx.op_buf);
   1177     if (rc) {
   1178         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
   1179         return rc;
   1180     }
   1181 
   1182     return rc;
   1183 }
   1184 
   1185 /* ======================================================================
   1186    FUNCTION
   1187    omx_vdec::OMXCntrlProcessMsgCb
   1188 
   1189    DESCRIPTION
   1190    IL Client callbacks are generated through this routine. The decoder
   1191    provides the thread context for this routine.
   1192 
   1193    PARAMETERS
   1194    ctxt -- Context information related to the self.
   1195    id   -- Event identifier. This could be any of the following:
   1196    1. Command completion event
   1197    2. Buffer done callback event
   1198    3. Frame done callback event
   1199 
   1200    RETURN VALUE
   1201    None.
   1202 
   1203    ========================================================================== */
   1204 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
   1205 {
   1206     unsigned long p1; // Parameter - 1
   1207     unsigned long p2; // Parameter - 2
   1208     unsigned long ident;
   1209     unsigned qsize=0; // qsize
   1210     omx_vdec *pThis = (omx_vdec *) ctxt;
   1211 
   1212     if (!pThis) {
   1213         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
   1214                 __func__);
   1215         return;
   1216     }
   1217 
   1218     // Protect the shared queue data structure
   1219     do {
   1220         /*Read the message id's from the queue*/
   1221         pthread_mutex_lock(&pThis->m_lock);
   1222         qsize = pThis->m_cmd_q.m_size;
   1223         if (qsize) {
   1224             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
   1225         }
   1226 
   1227         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1228             qsize = pThis->m_ftb_q.m_size;
   1229             if (qsize) {
   1230                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
   1231             }
   1232         }
   1233 
   1234         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1235             qsize = pThis->m_etb_q.m_size;
   1236             if (qsize) {
   1237                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
   1238             }
   1239         }
   1240         pthread_mutex_unlock(&pThis->m_lock);
   1241 
   1242         /*process message if we have one*/
   1243         if (qsize > 0) {
   1244             id = ident;
   1245             switch (id) {
   1246                 case OMX_COMPONENT_GENERATE_EVENT:
   1247                     if (pThis->m_cb.EventHandler) {
   1248                         switch (p1) {
   1249                             case OMX_CommandStateSet:
   1250                                 pThis->m_state = (OMX_STATETYPE) p2;
   1251                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
   1252                                         pThis->m_state);
   1253                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1254                                         OMX_EventCmdComplete, p1, p2, NULL);
   1255                                 break;
   1256 
   1257                             case OMX_EventError:
   1258                                 if (p2 == OMX_StateInvalid) {
   1259                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
   1260                                     pThis->m_state = (OMX_STATETYPE) p2;
   1261                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1262                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
   1263                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
   1264                                     pThis->omx_report_error();
   1265                                 } else {
   1266                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1267                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
   1268                                 }
   1269                                 break;
   1270 
   1271                             case OMX_CommandPortDisable:
   1272                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
   1273                                 if (BITMASK_PRESENT(&pThis->m_flags,
   1274                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1275                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1276                                     break;
   1277                                 }
   1278                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
   1279                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1280                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   1281                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
   1282                                         DEBUG_PRINT_HIGH("Failed to release output buffers");
   1283                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
   1284                                     pThis->in_reconfig = false;
   1285                                     if (eRet !=  OMX_ErrorNone) {
   1286                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
   1287                                         pThis->omx_report_error();
   1288                                         break;
   1289                                     }
   1290                                 }
   1291                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1292                                         OMX_EventCmdComplete, p1, p2, NULL );
   1293                                 break;
   1294                             case OMX_CommandPortEnable:
   1295                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
   1296                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
   1297                                         OMX_EventCmdComplete, p1, p2, NULL );
   1298                                 break;
   1299 
   1300                             default:
   1301                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1302                                         OMX_EventCmdComplete, p1, p2, NULL );
   1303                                 break;
   1304 
   1305                         }
   1306                     } else {
   1307                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1308                     }
   1309                     break;
   1310                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
   1311                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   1312                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1313                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
   1314                         pThis->omx_report_error ();
   1315                     }
   1316                     break;
   1317                 case OMX_COMPONENT_GENERATE_ETB: {
   1318                         OMX_ERRORTYPE iret;
   1319                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
   1320                         if (iret == OMX_ErrorInsufficientResources) {
   1321                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
   1322                             pThis->omx_report_hw_overload ();
   1323                         } else if (iret != OMX_ErrorNone) {
   1324                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
   1325                             pThis->omx_report_error ();
   1326                         }
   1327                     }
   1328                     break;
   1329 
   1330                 case OMX_COMPONENT_GENERATE_FTB:
   1331                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
   1332                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1333                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
   1334                         pThis->omx_report_error ();
   1335                     }
   1336                     break;
   1337 
   1338                 case OMX_COMPONENT_GENERATE_COMMAND:
   1339                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
   1340                             (OMX_U32)p2,(OMX_PTR)NULL);
   1341                     break;
   1342 
   1343                 case OMX_COMPONENT_GENERATE_EBD:
   1344 
   1345                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
   1346                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
   1347                         pThis->omx_report_error ();
   1348                     } else {
   1349                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
   1350                             pThis->time_stamp_dts.remove_time_stamp(
   1351                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
   1352                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1353                                     ?true:false);
   1354                         }
   1355 
   1356                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1357                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
   1358                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
   1359                             pThis->omx_report_error ();
   1360                         }
   1361                     }
   1362                     break;
   1363                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
   1364                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
   1365                                             if (p1) {
   1366                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
   1367                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1368                                                         ?true:false);
   1369                                                 free(timestamp);
   1370                                             }
   1371                                         }
   1372                                         break;
   1373                 case OMX_COMPONENT_GENERATE_FBD:
   1374                                         if (p2 != VDEC_S_SUCCESS) {
   1375                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
   1376                                             pThis->omx_report_error ();
   1377                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1378                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
   1379                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
   1380                                             pThis->omx_report_error ();
   1381                                         }
   1382                                         break;
   1383 
   1384                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1385                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
   1386                                         if (!pThis->input_flush_progress) {
   1387                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1388                                         } else {
   1389                                             pThis->execute_input_flush();
   1390                                             if (pThis->m_cb.EventHandler) {
   1391                                                 if (p2 != VDEC_S_SUCCESS) {
   1392                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1393                                                     pThis->omx_report_error ();
   1394                                                 } else {
   1395                                                     /*Check if we need generate event for Flush done*/
   1396                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1397                                                                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
   1398                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1399                                                         DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
   1400                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1401                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
   1402                                                                 OMX_CORE_INPUT_PORT_INDEX,NULL );
   1403                                                     }
   1404                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1405                                                                 OMX_COMPONENT_IDLE_PENDING)) {
   1406                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1407                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
   1408                                                             pThis->omx_report_error ();
   1409                                                         } else {
   1410                                                             pThis->streaming[OUTPUT_PORT] = false;
   1411                                                         }
   1412                                                         if (!pThis->output_flush_progress) {
   1413                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
   1414                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1415                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1416                                                         }
   1417                                                     }
   1418                                                 }
   1419                                             } else {
   1420                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1421                                             }
   1422                                         }
   1423                                         break;
   1424 
   1425                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1426                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
   1427                                         if (!pThis->output_flush_progress) {
   1428                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1429                                         } else {
   1430                                             pThis->execute_output_flush();
   1431                                             if (pThis->m_cb.EventHandler) {
   1432                                                 if (p2 != VDEC_S_SUCCESS) {
   1433                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1434                                                     pThis->omx_report_error ();
   1435                                                 } else {
   1436                                                     /*Check if we need generate event for Flush done*/
   1437                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1438                                                                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   1439                                                         DEBUG_PRINT_LOW("Notify Output Flush done");
   1440                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1441                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1442                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
   1443                                                                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   1444                                                     }
   1445                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1446                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1447                                                         DEBUG_PRINT_LOW("Internal flush complete");
   1448                                                         BITMASK_CLEAR (&pThis->m_flags,
   1449                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1450                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1451                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1452                                                             pThis->post_event(OMX_CommandPortDisable,
   1453                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1454                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1455                                                             BITMASK_CLEAR (&pThis->m_flags,
   1456                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1457                                                             BITMASK_CLEAR (&pThis->m_flags,
   1458                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1459 
   1460                                                         }
   1461                                                     }
   1462 
   1463                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1464                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1465                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
   1466                                                             pThis->omx_report_error ();
   1467                                                             break;
   1468                                                         }
   1469                                                         pThis->streaming[CAPTURE_PORT] = false;
   1470                                                         if (!pThis->input_flush_progress) {
   1471                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
   1472                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1473                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1474                                                         }
   1475                                                     }
   1476                                                 }
   1477                                             } else {
   1478                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1479                                             }
   1480                                         }
   1481                                         break;
   1482 
   1483                 case OMX_COMPONENT_GENERATE_START_DONE:
   1484                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1485 
   1486                                         if (pThis->m_cb.EventHandler) {
   1487                                             if (p2 != VDEC_S_SUCCESS) {
   1488                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
   1489                                                 pThis->omx_report_error ();
   1490                                             } else {
   1491                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
   1492                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1493                                                     DEBUG_PRINT_LOW("Move to executing");
   1494                                                     // Send the callback now
   1495                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1496                                                     pThis->m_state = OMX_StateExecuting;
   1497                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1498                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1499                                                             OMX_StateExecuting, NULL);
   1500                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1501                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1502                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1503                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1504                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
   1505                                                         pThis->omx_report_error ();
   1506                                                     }
   1507                                                 }
   1508                                             }
   1509                                         } else {
   1510                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
   1511                                         }
   1512                                         break;
   1513 
   1514                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1515                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1516                                         if (pThis->m_cb.EventHandler) {
   1517                                             if (p2 != VDEC_S_SUCCESS) {
   1518                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1519                                                 pThis->omx_report_error ();
   1520                                             } else {
   1521                                                 pThis->complete_pending_buffer_done_cbs();
   1522                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1523                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1524                                                     //Send the callback now
   1525                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1526                                                     pThis->m_state = OMX_StatePause;
   1527                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1528                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1529                                                             OMX_StatePause, NULL);
   1530                                                 }
   1531                                             }
   1532                                         } else {
   1533                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1534                                         }
   1535 
   1536                                         break;
   1537 
   1538                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1539                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1540                                         if (pThis->m_cb.EventHandler) {
   1541                                             if (p2 != VDEC_S_SUCCESS) {
   1542                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1543                                                 pThis->omx_report_error ();
   1544                                             } else {
   1545                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1546                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
   1547                                                     // Send the callback now
   1548                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1549                                                     pThis->m_state = OMX_StateExecuting;
   1550                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1551                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1552                                                             OMX_StateExecuting,NULL);
   1553                                                 }
   1554                                             }
   1555                                         } else {
   1556                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1557                                         }
   1558 
   1559                                         break;
   1560 
   1561                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1562                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1563                                         if (pThis->m_cb.EventHandler) {
   1564                                             if (p2 != VDEC_S_SUCCESS) {
   1565                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1566                                                 pThis->omx_report_error ();
   1567                                             } else {
   1568                                                 pThis->complete_pending_buffer_done_cbs();
   1569                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1570                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1571                                                     // Send the callback now
   1572                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1573                                                     pThis->m_state = OMX_StateIdle;
   1574                                                     DEBUG_PRINT_LOW("Move to Idle State");
   1575                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1576                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1577                                                             OMX_StateIdle,NULL);
   1578                                                 }
   1579                                             }
   1580                                         } else {
   1581                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1582                                         }
   1583 
   1584                                         break;
   1585 
   1586                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1587                                         if (p2 == OMX_IndexParamPortDefinition) {
   1588                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
   1589                                             pThis->in_reconfig = true;
   1590                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
   1591                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
   1592 
   1593                                             /* Check if resolution is changed in smooth streaming mode */
   1594                                             if (pThis->m_smoothstreaming_mode &&
   1595                                                 (pThis->framesize.nWidth !=
   1596                                                     pThis->drv_ctx.video_resolution.frame_width) ||
   1597                                                 (pThis->framesize.nHeight !=
   1598                                                     pThis->drv_ctx.video_resolution.frame_height)) {
   1599 
   1600                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
   1601                                                         pThis->framesize.nWidth,
   1602                                                         pThis->framesize.nHeight,
   1603                                                         pThis->drv_ctx.video_resolution.frame_width,
   1604                                                         pThis->drv_ctx.video_resolution.frame_height);
   1605 
   1606                                                 /* Update new resolution */
   1607                                                 pThis->framesize.nWidth =
   1608                                                        pThis->drv_ctx.video_resolution.frame_width;
   1609                                                 pThis->framesize.nHeight =
   1610                                                        pThis->drv_ctx.video_resolution.frame_height;
   1611 
   1612                                                 /* Update C2D with new resolution */
   1613                                                 if (!pThis->client_buffers.update_buffer_req()) {
   1614                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
   1615                                                 }
   1616                                             }
   1617 
   1618                                             /* Update new crop information */
   1619                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
   1620                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
   1621                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
   1622                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
   1623 
   1624                                             /* Validate the new crop information */
   1625                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
   1626                                                 pThis->drv_ctx.video_resolution.frame_width) {
   1627 
   1628                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
   1629                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
   1630                                                         pThis->drv_ctx.video_resolution.frame_width);
   1631                                                 pThis->rectangle.nLeft = 0;
   1632 
   1633                                                 if (pThis->rectangle.nWidth >
   1634                                                     pThis->drv_ctx.video_resolution.frame_width) {
   1635 
   1636                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
   1637                                                             pThis->rectangle.nWidth,
   1638                                                             pThis->drv_ctx.video_resolution.frame_width);
   1639                                                     pThis->rectangle.nWidth =
   1640                                                         pThis->drv_ctx.video_resolution.frame_width;
   1641                                                 }
   1642                                             }
   1643                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
   1644                                                 pThis->drv_ctx.video_resolution.frame_height) {
   1645 
   1646                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
   1647                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
   1648                                                     pThis->drv_ctx.video_resolution.frame_height);
   1649                                                 pThis->rectangle.nTop = 0;
   1650 
   1651                                                 if (pThis->rectangle.nHeight >
   1652                                                     pThis->drv_ctx.video_resolution.frame_height) {
   1653 
   1654                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
   1655                                                         pThis->rectangle.nHeight,
   1656                                                         pThis->drv_ctx.video_resolution.frame_height);
   1657                                                     pThis->rectangle.nHeight =
   1658                                                         pThis->drv_ctx.video_resolution.frame_height;
   1659                                                 }
   1660                                             }
   1661                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
   1662                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
   1663                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
   1664                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
   1665                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
   1666                                         } else {
   1667                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
   1668                                             break;
   1669                                         }
   1670                                         if (pThis->m_debug.outfile) {
   1671                                             fclose(pThis->m_debug.outfile);
   1672                                             pThis->m_debug.outfile = NULL;
   1673                                         }
   1674                                         if (pThis->m_debug.out_ymeta_file) {
   1675                                             fclose(pThis->m_debug.out_ymeta_file);
   1676                                             pThis->m_debug.out_ymeta_file = NULL;
   1677                                         }
   1678                                         if (pThis->m_debug.out_uvmeta_file) {
   1679                                             fclose(pThis->m_debug.out_uvmeta_file);
   1680                                             pThis->m_debug.out_uvmeta_file = NULL;
   1681                                         }
   1682 
   1683                                         if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) {
   1684                                             pThis->prefetchNewBuffers();
   1685                                         }
   1686 
   1687                                         if (pThis->m_cb.EventHandler) {
   1688                                             uint32_t frame_data[2];
   1689                                             frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ?
   1690                                                 pThis->m_reconfig_height : pThis->rectangle.nHeight;
   1691                                             frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ?
   1692                                                 pThis->m_reconfig_width : pThis->rectangle.nWidth;
   1693                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1694                                                     OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data );
   1695                                         } else {
   1696                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1697                                         }
   1698                                         break;
   1699 
   1700                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1701                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1702                                         if (pThis->m_cb.EventHandler) {
   1703                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1704                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1705                                         } else {
   1706                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1707                                         }
   1708                                         pThis->prev_ts = LLONG_MAX;
   1709                                         pThis->rst_prev_ts = true;
   1710                                         break;
   1711 
   1712                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1713                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1714                                         pThis->omx_report_error();
   1715                                         break;
   1716 
   1717                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1718                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
   1719                                         pThis->omx_report_unsupported_setting();
   1720                                         break;
   1721 
   1722                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
   1723                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
   1724                                         pThis->omx_report_hw_overload();
   1725                                         break;
   1726 
   1727                 default:
   1728                                         break;
   1729             }
   1730         }
   1731         pthread_mutex_lock(&pThis->m_lock);
   1732         qsize = pThis->m_cmd_q.m_size;
   1733         if (pThis->m_state != OMX_StatePause)
   1734             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1735         pthread_mutex_unlock(&pThis->m_lock);
   1736     } while (qsize>0);
   1737 
   1738 }
   1739 
   1740 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1741 {
   1742     int format_changed = 0;
   1743     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
   1744             (width != (int)drv_ctx.video_resolution.frame_width)) {
   1745         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
   1746                 width, drv_ctx.video_resolution.frame_width,
   1747                 height,drv_ctx.video_resolution.frame_height);
   1748         format_changed = 1;
   1749     }
   1750     drv_ctx.video_resolution.frame_height = height;
   1751     drv_ctx.video_resolution.frame_width = width;
   1752     drv_ctx.video_resolution.scan_lines = scan_lines;
   1753     drv_ctx.video_resolution.stride = stride;
   1754     if(!is_down_scalar_enabled) {
   1755         rectangle.nLeft = 0;
   1756         rectangle.nTop = 0;
   1757         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   1758         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   1759     }
   1760     return format_changed;
   1761 }
   1762 
   1763 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1764 {
   1765     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1766                 OMX_MAX_STRINGNAME_SIZE) &&
   1767             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1768         m_decoder_capability.max_width = 1280;
   1769         m_decoder_capability.max_height = 720;
   1770         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1771     }
   1772 
   1773     if ((drv_ctx.video_resolution.frame_width *
   1774                 drv_ctx.video_resolution.frame_height >
   1775                 m_decoder_capability.max_width *
   1776                 m_decoder_capability.max_height) ||
   1777             (drv_ctx.video_resolution.frame_width*
   1778              drv_ctx.video_resolution.frame_height <
   1779              m_decoder_capability.min_width *
   1780              m_decoder_capability.min_height)) {
   1781         DEBUG_PRINT_ERROR(
   1782                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1783                 drv_ctx.video_resolution.frame_width,
   1784                 drv_ctx.video_resolution.frame_height,
   1785                 m_decoder_capability.min_width,
   1786                 m_decoder_capability.min_height,
   1787                 m_decoder_capability.max_width,
   1788                 m_decoder_capability.max_height);
   1789         return OMX_ErrorUnsupportedSetting;
   1790     }
   1791     DEBUG_PRINT_HIGH("video session supported");
   1792     return OMX_ErrorNone;
   1793 }
   1794 
   1795 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
   1796 {
   1797     if (m_debug.in_buffer_log && !m_debug.infile) {
   1798         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   1799            snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v",
   1800                    m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1801         } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   1802                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc,
   1803                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1804         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   1805                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263",
   1806                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1807         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
   1808                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   1809                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
   1810                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1811         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   1812                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
   1813                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1814         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   1815                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   1816                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1817         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
   1818                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   1819                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1820         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   1821                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   1822                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1823         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1824                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   1825                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1826         } else {
   1827                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx",
   1828                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1829         }
   1830         m_debug.infile = fopen (m_debug.infile_name, "ab");
   1831         if (!m_debug.infile) {
   1832             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   1833             m_debug.infile_name[0] = '\0';
   1834             return -1;
   1835         }
   1836         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   1837                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1838             struct ivf_file_header {
   1839                 OMX_U8 signature[4]; //='DKIF';
   1840                 OMX_U8 version         ; //= 0;
   1841                 OMX_U8 headersize      ; //= 32;
   1842                 OMX_U32 FourCC;
   1843                 OMX_U8 width;
   1844                 OMX_U8 height;
   1845                 OMX_U32 rate;
   1846                 OMX_U32 scale;
   1847                 OMX_U32 length;
   1848                 OMX_U8 unused[4];
   1849             } file_header;
   1850 
   1851             memset((void *)&file_header,0,sizeof(file_header));
   1852             file_header.signature[0] = 'D';
   1853             file_header.signature[1] = 'K';
   1854             file_header.signature[2] = 'I';
   1855             file_header.signature[3] = 'F';
   1856             file_header.version = 0;
   1857             file_header.headersize = 32;
   1858             switch (drv_ctx.decoder_format) {
   1859                 case VDEC_CODECTYPE_VP8:
   1860                     file_header.FourCC = 0x30385056;
   1861                     break;
   1862                 case VDEC_CODECTYPE_VP9:
   1863                     file_header.FourCC = 0x30395056;
   1864                     break;
   1865                 default:
   1866                     DEBUG_PRINT_ERROR("unsupported format for VP8/VP9");
   1867                     break;
   1868             }
   1869             fwrite((const char *)&file_header,
   1870                     sizeof(file_header),1,m_debug.infile);
   1871          }
   1872     }
   1873     if (m_debug.infile && buffer_addr && buffer_len) {
   1874         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   1875                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1876             struct vpx_ivf_frame_header {
   1877                 OMX_U32 framesize;
   1878                 OMX_U32 timestamp_lo;
   1879                 OMX_U32 timestamp_hi;
   1880             } vpx_frame_header;
   1881             vpx_frame_header.framesize = buffer_len;
   1882             /* Currently FW doesn't use timestamp values */
   1883             vpx_frame_header.timestamp_lo = 0;
   1884             vpx_frame_header.timestamp_hi = 0;
   1885             fwrite((const char *)&vpx_frame_header,
   1886                     sizeof(vpx_frame_header),1,m_debug.infile);
   1887         }
   1888         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
   1889     }
   1890     return 0;
   1891 }
   1892 
   1893 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
   1894     int buf_index = 0;
   1895     char *temp = NULL;
   1896 
   1897     if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) {
   1898         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv",
   1899                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1900         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
   1901         if (!m_debug.outfile) {
   1902             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
   1903             m_debug.outfile_name[0] = '\0';
   1904             return -1;
   1905         }
   1906     }
   1907 
   1908     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file
   1909         && buffer->nFilledLen) {
   1910         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
   1911                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1912         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
   1913                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1914         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
   1915         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
   1916         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
   1917             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
   1918             m_debug.out_ymetafile_name[0] = '\0';
   1919             m_debug.out_uvmetafile_name[0] = '\0';
   1920             return -1;
   1921         }
   1922     }
   1923 
   1924     if ((!m_debug.outfile && !m_debug.out_ymeta_file) || !buffer || !buffer->nFilledLen)
   1925         return 0;
   1926 
   1927     buf_index = buffer - m_out_mem_ptr;
   1928     temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   1929 
   1930     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   1931         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
   1932             drv_ctx.video_resolution.frame_width,
   1933             drv_ctx.video_resolution.frame_height);
   1934 
   1935         if (m_debug.outfile)
   1936             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
   1937 
   1938         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
   1939             unsigned int width = 0, height = 0;
   1940             unsigned int y_plane, y_meta_plane;
   1941             int y_stride = 0, y_sclines = 0;
   1942             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
   1943             int color_fmt = COLOR_FMT_NV12_UBWC;
   1944             int i;
   1945             int bytes_written = 0;
   1946 
   1947             width = drv_ctx.video_resolution.frame_width;
   1948             height = drv_ctx.video_resolution.frame_height;
   1949             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
   1950             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
   1951             y_stride = VENUS_Y_STRIDE(color_fmt, width);
   1952             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
   1953             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
   1954             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
   1955 
   1956             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
   1957             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
   1958 
   1959             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   1960             for (i = 0; i < y_meta_scanlines; i++) {
   1961                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
   1962                  temp += y_meta_stride;
   1963             }
   1964 
   1965             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
   1966             for(i = 0; i < uv_meta_scanlines; i++) {
   1967                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
   1968                 temp += uv_meta_stride;
   1969             }
   1970         }
   1971     } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12 && m_debug.outfile) {
   1972         int stride = drv_ctx.video_resolution.stride;
   1973         int scanlines = drv_ctx.video_resolution.scan_lines;
   1974         if (m_smoothstreaming_mode) {
   1975             stride = drv_ctx.video_resolution.frame_width;
   1976             scanlines = drv_ctx.video_resolution.frame_height;
   1977             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
   1978             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
   1979         }
   1980         unsigned i;
   1981         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
   1982             drv_ctx.video_resolution.frame_width,
   1983             drv_ctx.video_resolution.frame_height, stride, scanlines);
   1984         int bytes_written = 0;
   1985         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   1986              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1987              temp += stride;
   1988         }
   1989         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   1990         int stride_c = stride;
   1991         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   1992             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1993             temp += stride_c;
   1994         }
   1995     }
   1996     return 0;
   1997 }
   1998 
   1999 /* ======================================================================
   2000    FUNCTION
   2001    omx_vdec::ComponentInit
   2002 
   2003    DESCRIPTION
   2004    Initialize the component.
   2005 
   2006    PARAMETERS
   2007    ctxt -- Context information related to the self.
   2008    id   -- Event identifier. This could be any of the following:
   2009    1. Command completion event
   2010    2. Buffer done callback event
   2011    3. Frame done callback event
   2012 
   2013    RETURN VALUE
   2014    None.
   2015 
   2016    ========================================================================== */
   2017 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   2018 {
   2019 
   2020     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2021     struct v4l2_fmtdesc fdesc;
   2022     struct v4l2_format fmt;
   2023     struct v4l2_requestbuffers bufreq;
   2024     struct v4l2_control control;
   2025     struct v4l2_frmsizeenum frmsize;
   2026     unsigned int   alignment = 0,buffer_size = 0;
   2027     int fds[2];
   2028     int r,ret=0;
   2029     bool codec_ambiguous = false;
   2030     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
   2031     char property_value[PROPERTY_VALUE_MAX] = {0};
   2032     FILE *soc_file = NULL;
   2033     char buffer[10];
   2034 
   2035 #ifdef _ANDROID_
   2036     char platform_name[PROPERTY_VALUE_MAX];
   2037     property_get("ro.board.platform", platform_name, "0");
   2038     if (!strncmp(platform_name, "msm8610", 7)) {
   2039         device_name = (OMX_STRING)"/dev/video/q6_dec";
   2040         is_q6_platform = true;
   2041         maxSmoothStreamingWidth = 1280;
   2042         maxSmoothStreamingHeight = 720;
   2043     }
   2044 #endif
   2045 
   2046     is_thulium_v1 = false;
   2047     soc_file = fopen("/sys/devices/soc0/soc_id", "r");
   2048     if (soc_file) {
   2049         fread(buffer, 1, 4, soc_file);
   2050         fclose(soc_file);
   2051         if (atoi(buffer) == 246) {
   2052             soc_file = fopen("/sys/devices/soc0/revision", "r");
   2053             if (soc_file) {
   2054                 fread(buffer, 1, 4, soc_file);
   2055                 fclose(soc_file);
   2056                 if (atoi(buffer) == 1) {
   2057                     is_thulium_v1 = true;
   2058                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
   2059                 }
   2060             }
   2061         }
   2062     }
   2063 
   2064 #ifdef _ANDROID_
   2065     /*
   2066      * turn off frame parsing for Android by default.
   2067      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
   2068      */
   2069     arbitrary_bytes = false;
   2070     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   2071     if (atoi(property_value)) {
   2072         DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
   2073         arbitrary_bytes = true;
   2074     }
   2075 #endif
   2076 
   2077     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
   2078                 OMX_MAX_STRINGNAME_SIZE)) {
   2079         secure_mode = true;
   2080         arbitrary_bytes = false;
   2081         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   2082     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
   2083                 OMX_MAX_STRINGNAME_SIZE)) {
   2084         secure_mode = true;
   2085         arbitrary_bytes = false;
   2086         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
   2087     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
   2088                 OMX_MAX_STRINGNAME_SIZE)) {
   2089         secure_mode = true;
   2090         arbitrary_bytes = false;
   2091         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
   2092     } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
   2093                 OMX_MAX_STRINGNAME_SIZE)) {
   2094         secure_mode = true;
   2095         arbitrary_bytes = false;
   2096         role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
   2097     } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
   2098                 OMX_MAX_STRINGNAME_SIZE)) {
   2099         secure_mode = true;
   2100         arbitrary_bytes = false;
   2101         role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
   2102     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
   2103                 OMX_MAX_STRINGNAME_SIZE)) {
   2104         secure_mode = true;
   2105         arbitrary_bytes = false;
   2106         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
   2107     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
   2108                 OMX_MAX_STRINGNAME_SIZE)) {
   2109         secure_mode = true;
   2110         arbitrary_bytes = false;
   2111         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
   2112     }
   2113 
   2114     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   2115 
   2116     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
   2117 
   2118     if (drv_ctx.video_driver_fd < 0) {
   2119         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
   2120         return OMX_ErrorInsufficientResources;
   2121     }
   2122     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   2123     drv_ctx.frame_rate.fps_denominator = 1;
   2124     m_poll_efd = eventfd(0, 0);
   2125     if (m_poll_efd < 0) {
   2126         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
   2127         return OMX_ErrorInsufficientResources;
   2128     }
   2129     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   2130     if (!ret) {
   2131         async_thread_created = true;
   2132         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   2133     }
   2134     if (ret) {
   2135         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
   2136         async_thread_created = false;
   2137         return OMX_ErrorInsufficientResources;
   2138     }
   2139 
   2140 #ifdef OUTPUT_EXTRADATA_LOG
   2141     outputExtradataFile = fopen (output_extradata_filename, "ab");
   2142 #endif
   2143 
   2144     // Copy the role information which provides the decoder kind
   2145     strlcpy(drv_ctx.kind,role,128);
   2146 
   2147     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   2148                 OMX_MAX_STRINGNAME_SIZE)) {
   2149         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   2150                 OMX_MAX_STRINGNAME_SIZE);
   2151         drv_ctx.timestamp_adjust = true;
   2152         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   2153         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   2154         output_capability=V4L2_PIX_FMT_MPEG4;
   2155         /*Initialize Start Code for MPEG4*/
   2156         codec_type_parse = CODEC_TYPE_MPEG4;
   2157         m_frame_parser.init_start_codes(codec_type_parse);
   2158     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   2159                 OMX_MAX_STRINGNAME_SIZE)) {
   2160         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   2161                 OMX_MAX_STRINGNAME_SIZE);
   2162         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   2163         output_capability = V4L2_PIX_FMT_MPEG2;
   2164         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   2165         /*Initialize Start Code for MPEG2*/
   2166         codec_type_parse = CODEC_TYPE_MPEG2;
   2167         m_frame_parser.init_start_codes(codec_type_parse);
   2168     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   2169                 OMX_MAX_STRINGNAME_SIZE)) {
   2170         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   2171         DEBUG_PRINT_LOW("H263 Decoder selected");
   2172         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   2173         eCompressionFormat = OMX_VIDEO_CodingH263;
   2174         output_capability = V4L2_PIX_FMT_H263;
   2175         codec_type_parse = CODEC_TYPE_H263;
   2176         m_frame_parser.init_start_codes(codec_type_parse);
   2177     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   2178                 OMX_MAX_STRINGNAME_SIZE)) {
   2179         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2180         DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
   2181         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   2182         output_capability = V4L2_PIX_FMT_DIVX_311;
   2183         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2184         codec_type_parse = CODEC_TYPE_DIVX;
   2185         m_frame_parser.init_start_codes(codec_type_parse);
   2186 
   2187     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   2188                 OMX_MAX_STRINGNAME_SIZE)) {
   2189         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2190         DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
   2191         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   2192         output_capability = V4L2_PIX_FMT_DIVX;
   2193         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2194         codec_type_parse = CODEC_TYPE_DIVX;
   2195         codec_ambiguous = true;
   2196         m_frame_parser.init_start_codes(codec_type_parse);
   2197 
   2198     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   2199                 OMX_MAX_STRINGNAME_SIZE)) {
   2200         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2201         DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
   2202         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   2203         output_capability = V4L2_PIX_FMT_DIVX;
   2204         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2205         codec_type_parse = CODEC_TYPE_DIVX;
   2206         codec_ambiguous = true;
   2207         m_frame_parser.init_start_codes(codec_type_parse);
   2208 
   2209     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   2210                 OMX_MAX_STRINGNAME_SIZE)) {
   2211         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   2212         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   2213         output_capability=V4L2_PIX_FMT_H264;
   2214         eCompressionFormat = OMX_VIDEO_CodingAVC;
   2215         codec_type_parse = CODEC_TYPE_H264;
   2216         m_frame_parser.init_start_codes(codec_type_parse);
   2217         m_frame_parser.init_nal_length(nal_length);
   2218         if (is_thulium_v1) {
   2219             arbitrary_bytes = true;
   2220             DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264");
   2221         }
   2222     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
   2223                 OMX_MAX_STRINGNAME_SIZE)) {
   2224         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   2225         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
   2226         output_capability = V4L2_PIX_FMT_H264_MVC;
   2227         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
   2228         codec_type_parse = CODEC_TYPE_H264;
   2229         m_frame_parser.init_start_codes(codec_type_parse);
   2230         m_frame_parser.init_nal_length(nal_length);
   2231     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
   2232                 OMX_MAX_STRINGNAME_SIZE)) {
   2233         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
   2234         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
   2235         output_capability = V4L2_PIX_FMT_HEVC;
   2236         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
   2237         codec_type_parse = CODEC_TYPE_HEVC;
   2238         m_frame_parser.init_start_codes(codec_type_parse);
   2239         m_frame_parser.init_nal_length(nal_length);
   2240     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   2241                 OMX_MAX_STRINGNAME_SIZE)) {
   2242         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2243         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   2244         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2245         codec_type_parse = CODEC_TYPE_VC1;
   2246         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   2247         m_frame_parser.init_start_codes(codec_type_parse);
   2248     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   2249                 OMX_MAX_STRINGNAME_SIZE)) {
   2250         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2251         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   2252         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2253         codec_type_parse = CODEC_TYPE_VC1;
   2254         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   2255         m_frame_parser.init_start_codes(codec_type_parse);
   2256     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   2257                 OMX_MAX_STRINGNAME_SIZE)) {
   2258         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   2259         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
   2260         output_capability = V4L2_PIX_FMT_VP8;
   2261         eCompressionFormat = OMX_VIDEO_CodingVP8;
   2262         codec_type_parse = CODEC_TYPE_VP8;
   2263         arbitrary_bytes = false;
   2264     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
   2265                 OMX_MAX_STRINGNAME_SIZE)) {
   2266         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   2267         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
   2268         output_capability = V4L2_PIX_FMT_VP9;
   2269         eCompressionFormat = OMX_VIDEO_CodingVP9;
   2270         codec_type_parse = CODEC_TYPE_VP9;
   2271         arbitrary_bytes = false;
   2272     } else {
   2273         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
   2274         eRet = OMX_ErrorInvalidComponentName;
   2275     }
   2276 
   2277     if (eRet == OMX_ErrorNone) {
   2278         OMX_COLOR_FORMATTYPE dest_color_format;
   2279         if (m_disable_ubwc_mode) {
   2280             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   2281         } else {
   2282             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   2283         }
   2284         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
   2285             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2286                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   2287         else
   2288             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2289                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2290         if (!client_buffers.set_color_format(dest_color_format)) {
   2291             DEBUG_PRINT_ERROR("Setting color format failed");
   2292             eRet = OMX_ErrorInsufficientResources;
   2293         }
   2294 
   2295         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
   2296 
   2297         if (m_disable_ubwc_mode) {
   2298             capture_capability = V4L2_PIX_FMT_NV12;
   2299         } else {
   2300             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   2301         }
   2302 
   2303         struct v4l2_capability cap;
   2304         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   2305         if (ret) {
   2306             DEBUG_PRINT_ERROR("Failed to query capabilities");
   2307             /*TODO: How to handle this case */
   2308         } else {
   2309             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   2310                 " version = %d, capabilities = %x", cap.driver, cap.card,
   2311                 cap.bus_info, cap.version, cap.capabilities);
   2312         }
   2313         ret=0;
   2314         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2315         fdesc.index=0;
   2316         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2317             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2318                     fdesc.pixelformat, fdesc.flags);
   2319             fdesc.index++;
   2320         }
   2321         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2322         fdesc.index=0;
   2323         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2324 
   2325             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2326                     fdesc.pixelformat, fdesc.flags);
   2327             fdesc.index++;
   2328         }
   2329         update_resolution(320, 240, 320, 240);
   2330         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2331         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2332         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2333         fmt.fmt.pix_mp.pixelformat = output_capability;
   2334         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2335         if (ret) {
   2336             /*TODO: How to handle this case */
   2337             DEBUG_PRINT_ERROR("Failed to set format on output port");
   2338             return OMX_ErrorInsufficientResources;
   2339         }
   2340         DEBUG_PRINT_HIGH("Set Format was successful");
   2341         if (codec_ambiguous) {
   2342             if (output_capability == V4L2_PIX_FMT_DIVX) {
   2343                 struct v4l2_control divx_ctrl;
   2344 
   2345                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   2346                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   2347                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   2348                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   2349                 } else {
   2350                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   2351                 }
   2352 
   2353                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   2354                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   2355                 if (ret) {
   2356                     DEBUG_PRINT_ERROR("Failed to set divx version");
   2357                 }
   2358             } else {
   2359                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   2360             }
   2361         }
   2362 
   2363         property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
   2364         m_conceal_color= atoi(property_value);
   2365         DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
   2366         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
   2367         control.value = m_conceal_color;
   2368         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2369         if (ret) {
   2370             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
   2371         }
   2372 
   2373         //Get the hardware capabilities
   2374         memset((void *)&frmsize,0,sizeof(frmsize));
   2375         frmsize.index = 0;
   2376         frmsize.pixel_format = output_capability;
   2377         ret = ioctl(drv_ctx.video_driver_fd,
   2378                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   2379         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   2380             DEBUG_PRINT_ERROR("Failed to get framesizes");
   2381             return OMX_ErrorHardware;
   2382         }
   2383 
   2384         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   2385             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   2386             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   2387             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   2388             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   2389         }
   2390 
   2391         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   2392         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2393         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2394         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2395         fmt.fmt.pix_mp.pixelformat = capture_capability;
   2396         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2397         if (ret) {
   2398             /*TODO: How to handle this case */
   2399             DEBUG_PRINT_ERROR("Failed to set format on capture port");
   2400         }
   2401         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
   2402         framesize.nWidth = drv_ctx.video_resolution.frame_width;
   2403         framesize.nHeight = drv_ctx.video_resolution.frame_height;
   2404 
   2405         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
   2406         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   2407         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   2408 
   2409         DEBUG_PRINT_HIGH("Set Format was successful");
   2410         if (secure_mode) {
   2411             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   2412             control.value = 1;
   2413             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
   2414             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   2415             if (ret) {
   2416                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
   2417                 return OMX_ErrorInsufficientResources;
   2418             }
   2419         }
   2420         if (output_capability == V4L2_PIX_FMT_H264_MVC) {
   2421             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
   2422             control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
   2423             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2424             if (ret) {
   2425                 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
   2426                 return OMX_ErrorInsufficientResources;
   2427             }
   2428         }
   2429 
   2430         if (is_thulium_v1) {
   2431             eRet = enable_smoothstreaming();
   2432             if (eRet != OMX_ErrorNone) {
   2433                DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver");
   2434                return eRet;
   2435             }
   2436         }
   2437 
   2438         /*Get the Buffer requirements for input and output ports*/
   2439         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2440         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2441 
   2442         if (secure_mode) {
   2443             drv_ctx.op_buf.alignment = SECURE_ALIGN;
   2444             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
   2445         } else {
   2446             drv_ctx.op_buf.alignment = SZ_4K;
   2447             drv_ctx.ip_buf.alignment = SZ_4K;
   2448         }
   2449 
   2450         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   2451         drv_ctx.extradata = 0;
   2452         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   2453         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   2454         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   2455         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2456         drv_ctx.idr_only_decoding = 0;
   2457 
   2458 #ifdef _ANDROID_
   2459         property_get("vidc.dec.downscalar_width",property_value,"0");
   2460         if (atoi(property_value)) {
   2461             m_downscalar_width = atoi(property_value);
   2462         }
   2463         property_get("vidc.dec.downscalar_height",property_value,"0");
   2464         if (atoi(property_value)) {
   2465             m_downscalar_height = atoi(property_value);
   2466         }
   2467 
   2468         if (m_downscalar_width < m_decoder_capability.min_width ||
   2469             m_downscalar_height < m_decoder_capability.min_height) {
   2470             m_downscalar_width = 0;
   2471             m_downscalar_height = 0;
   2472         }
   2473 
   2474         DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n",
   2475             m_downscalar_width, m_downscalar_height);
   2476 #endif
   2477         m_state = OMX_StateLoaded;
   2478 #ifdef DEFAULT_EXTRADATA
   2479         if ((strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
   2480                     OMX_MAX_STRINGNAME_SIZE) &&
   2481                 strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",
   2482                         OMX_MAX_STRINGNAME_SIZE)) &&
   2483                 (eRet == OMX_ErrorNone))
   2484                 enable_extradata(DEFAULT_EXTRADATA, true, true);
   2485 #endif
   2486         eRet = get_buffer_req(&drv_ctx.ip_buf);
   2487         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
   2488         get_buffer_req(&drv_ctx.op_buf);
   2489         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2490                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
   2491                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2492                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   2493                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   2494                     h264_scratch.nFilledLen = 0;
   2495                     h264_scratch.nOffset = 0;
   2496 
   2497                     if (h264_scratch.pBuffer == NULL) {
   2498                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
   2499                         return OMX_ErrorInsufficientResources;
   2500                     }
   2501         }
   2502         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2503             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2504             if (m_frame_parser.mutils == NULL) {
   2505                 m_frame_parser.mutils = new H264_Utils();
   2506                 if (m_frame_parser.mutils == NULL) {
   2507                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
   2508                     eRet = OMX_ErrorInsufficientResources;
   2509                 } else {
   2510                     m_frame_parser.mutils->initialize_frame_checking_environment();
   2511                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   2512                 }
   2513             }
   2514 
   2515             h264_parser = new h264_stream_parser();
   2516             if (!h264_parser) {
   2517                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   2518                 eRet = OMX_ErrorInsufficientResources;
   2519             }
   2520         }
   2521 
   2522         if (pipe(fds)) {
   2523             DEBUG_PRINT_ERROR("pipe creation failed");
   2524             eRet = OMX_ErrorInsufficientResources;
   2525         } else {
   2526             m_pipe_in = fds[0];
   2527             m_pipe_out = fds[1];
   2528             msg_thread_created = true;
   2529             r = pthread_create(&msg_thread_id,0,message_thread,this);
   2530 
   2531             if (r < 0) {
   2532                 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
   2533                 msg_thread_created = false;
   2534                 eRet = OMX_ErrorInsufficientResources;
   2535             }
   2536         }
   2537     }
   2538 
   2539     if (eRet != OMX_ErrorNone) {
   2540         DEBUG_PRINT_ERROR("Component Init Failed");
   2541     } else {
   2542         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
   2543                 drv_ctx.video_driver_fd);
   2544     }
   2545     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   2546     return eRet;
   2547 }
   2548 
   2549 /* ======================================================================
   2550    FUNCTION
   2551    omx_vdec::GetComponentVersion
   2552 
   2553    DESCRIPTION
   2554    Returns the component version.
   2555 
   2556    PARAMETERS
   2557    TBD.
   2558 
   2559    RETURN VALUE
   2560    OMX_ErrorNone.
   2561 
   2562    ========================================================================== */
   2563 OMX_ERRORTYPE  omx_vdec::get_component_version
   2564 (
   2565  OMX_IN OMX_HANDLETYPE hComp,
   2566  OMX_OUT OMX_STRING componentName,
   2567  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   2568  OMX_OUT OMX_VERSIONTYPE* specVersion,
   2569  OMX_OUT OMX_UUIDTYPE* componentUUID
   2570  )
   2571 {
   2572     (void) hComp;
   2573     (void) componentName;
   2574     (void) componentVersion;
   2575     (void) componentUUID;
   2576     if (m_state == OMX_StateInvalid) {
   2577         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
   2578         return OMX_ErrorInvalidState;
   2579     }
   2580     /* TBD -- Return the proper version */
   2581     if (specVersion) {
   2582         specVersion->nVersion = OMX_SPEC_VERSION;
   2583     }
   2584     return OMX_ErrorNone;
   2585 }
   2586 /* ======================================================================
   2587    FUNCTION
   2588    omx_vdec::SendCommand
   2589 
   2590    DESCRIPTION
   2591    Returns zero if all the buffers released..
   2592 
   2593    PARAMETERS
   2594    None.
   2595 
   2596    RETURN VALUE
   2597    true/false
   2598 
   2599    ========================================================================== */
   2600 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   2601         OMX_IN OMX_COMMANDTYPE cmd,
   2602         OMX_IN OMX_U32 param1,
   2603         OMX_IN OMX_PTR cmdData
   2604         )
   2605 {
   2606     (void) hComp;
   2607     (void) cmdData;
   2608     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
   2609     if (m_state == OMX_StateInvalid) {
   2610         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
   2611         return OMX_ErrorInvalidState;
   2612     }
   2613     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   2614             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   2615         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
   2616                 "to invalid port: %u", (unsigned int)param1);
   2617         return OMX_ErrorBadPortIndex;
   2618     }
   2619 
   2620     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   2621     sem_wait(&m_cmd_lock);
   2622     DEBUG_PRINT_LOW("send_command: Command Processed");
   2623     return OMX_ErrorNone;
   2624 }
   2625 
   2626 /* ======================================================================
   2627    FUNCTION
   2628    omx_vdec::SendCommand
   2629 
   2630    DESCRIPTION
   2631    Returns zero if all the buffers released..
   2632 
   2633    PARAMETERS
   2634    None.
   2635 
   2636    RETURN VALUE
   2637    true/false
   2638 
   2639    ========================================================================== */
   2640 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   2641         OMX_IN OMX_COMMANDTYPE cmd,
   2642         OMX_IN OMX_U32 param1,
   2643         OMX_IN OMX_PTR cmdData
   2644         )
   2645 {
   2646     (void) hComp;
   2647     (void) cmdData;
   2648     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2649     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   2650     int bFlag = 1,sem_posted = 0,ret=0;
   2651 
   2652     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
   2653     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
   2654             m_state, eState);
   2655 
   2656     if (cmd == OMX_CommandStateSet) {
   2657         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   2658         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   2659         /***************************/
   2660         /* Current State is Loaded */
   2661         /***************************/
   2662         if (m_state == OMX_StateLoaded) {
   2663             if (eState == OMX_StateIdle) {
   2664                 //if all buffers are allocated or all ports disabled
   2665                 if (allocate_done() ||
   2666                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   2667                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
   2668                 } else {
   2669                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
   2670                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   2671                     // Skip the event notification
   2672                     bFlag = 0;
   2673                 }
   2674             }
   2675             /* Requesting transition from Loaded to Loaded */
   2676             else if (eState == OMX_StateLoaded) {
   2677                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
   2678                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2679                         OMX_COMPONENT_GENERATE_EVENT);
   2680                 eRet = OMX_ErrorSameState;
   2681             }
   2682             /* Requesting transition from Loaded to WaitForResources */
   2683             else if (eState == OMX_StateWaitForResources) {
   2684                 /* Since error is None , we will post an event
   2685                    at the end of this function definition */
   2686                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
   2687             }
   2688             /* Requesting transition from Loaded to Executing */
   2689             else if (eState == OMX_StateExecuting) {
   2690                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
   2691                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2692                         OMX_COMPONENT_GENERATE_EVENT);
   2693                 eRet = OMX_ErrorIncorrectStateTransition;
   2694             }
   2695             /* Requesting transition from Loaded to Pause */
   2696             else if (eState == OMX_StatePause) {
   2697                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
   2698                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2699                         OMX_COMPONENT_GENERATE_EVENT);
   2700                 eRet = OMX_ErrorIncorrectStateTransition;
   2701             }
   2702             /* Requesting transition from Loaded to Invalid */
   2703             else if (eState == OMX_StateInvalid) {
   2704                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
   2705                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2706                 eRet = OMX_ErrorInvalidState;
   2707             } else {
   2708                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
   2709                         eState);
   2710                 eRet = OMX_ErrorBadParameter;
   2711             }
   2712         }
   2713 
   2714         /***************************/
   2715         /* Current State is IDLE */
   2716         /***************************/
   2717         else if (m_state == OMX_StateIdle) {
   2718             if (eState == OMX_StateLoaded) {
   2719                 if (release_done()) {
   2720                     /*
   2721                        Since error is None , we will post an event at the end
   2722                        of this function definition
   2723                      */
   2724                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
   2725                 } else {
   2726                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
   2727                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   2728                     // Skip the event notification
   2729                     bFlag = 0;
   2730                 }
   2731             }
   2732             /* Requesting transition from Idle to Executing */
   2733             else if (eState == OMX_StateExecuting) {
   2734                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2735                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   2736                 bFlag = 1;
   2737                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2738                 m_state=OMX_StateExecuting;
   2739                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
   2740             }
   2741             /* Requesting transition from Idle to Idle */
   2742             else if (eState == OMX_StateIdle) {
   2743                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
   2744                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2745                         OMX_COMPONENT_GENERATE_EVENT);
   2746                 eRet = OMX_ErrorSameState;
   2747             }
   2748             /* Requesting transition from Idle to WaitForResources */
   2749             else if (eState == OMX_StateWaitForResources) {
   2750                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
   2751                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2752                         OMX_COMPONENT_GENERATE_EVENT);
   2753                 eRet = OMX_ErrorIncorrectStateTransition;
   2754             }
   2755             /* Requesting transition from Idle to Pause */
   2756             else if (eState == OMX_StatePause) {
   2757                 /*To pause the Video core we need to start the driver*/
   2758                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   2759                       NULL) < */0) {
   2760                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
   2761                     omx_report_error ();
   2762                     eRet = OMX_ErrorHardware;
   2763                 } else {
   2764                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   2765                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
   2766                     bFlag = 0;
   2767                 }
   2768             }
   2769             /* Requesting transition from Idle to Invalid */
   2770             else if (eState == OMX_StateInvalid) {
   2771                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
   2772                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2773                 eRet = OMX_ErrorInvalidState;
   2774             } else {
   2775                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
   2776                 eRet = OMX_ErrorBadParameter;
   2777             }
   2778         }
   2779 
   2780         /******************************/
   2781         /* Current State is Executing */
   2782         /******************************/
   2783         else if (m_state == OMX_StateExecuting) {
   2784             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
   2785             /* Requesting transition from Executing to Idle */
   2786             if (eState == OMX_StateIdle) {
   2787                 /* Since error is None , we will post an event
   2788                    at the end of this function definition
   2789                  */
   2790                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
   2791                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2792                 if (!sem_posted) {
   2793                     sem_posted = 1;
   2794                     sem_post (&m_cmd_lock);
   2795                     execute_omx_flush(OMX_ALL);
   2796                 }
   2797                 bFlag = 0;
   2798             }
   2799             /* Requesting transition from Executing to Paused */
   2800             else if (eState == OMX_StatePause) {
   2801                 DEBUG_PRINT_LOW("PAUSE Command Issued");
   2802                 m_state = OMX_StatePause;
   2803                 bFlag = 1;
   2804             }
   2805             /* Requesting transition from Executing to Loaded */
   2806             else if (eState == OMX_StateLoaded) {
   2807                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
   2808                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2809                         OMX_COMPONENT_GENERATE_EVENT);
   2810                 eRet = OMX_ErrorIncorrectStateTransition;
   2811             }
   2812             /* Requesting transition from Executing to WaitForResources */
   2813             else if (eState == OMX_StateWaitForResources) {
   2814                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
   2815                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2816                         OMX_COMPONENT_GENERATE_EVENT);
   2817                 eRet = OMX_ErrorIncorrectStateTransition;
   2818             }
   2819             /* Requesting transition from Executing to Executing */
   2820             else if (eState == OMX_StateExecuting) {
   2821                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
   2822                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2823                         OMX_COMPONENT_GENERATE_EVENT);
   2824                 eRet = OMX_ErrorSameState;
   2825             }
   2826             /* Requesting transition from Executing to Invalid */
   2827             else if (eState == OMX_StateInvalid) {
   2828                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
   2829                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2830                 eRet = OMX_ErrorInvalidState;
   2831             } else {
   2832                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
   2833                 eRet = OMX_ErrorBadParameter;
   2834             }
   2835         }
   2836         /***************************/
   2837         /* Current State is Pause  */
   2838         /***************************/
   2839         else if (m_state == OMX_StatePause) {
   2840             /* Requesting transition from Pause to Executing */
   2841             if (eState == OMX_StateExecuting) {
   2842                 DEBUG_PRINT_LOW("Pause --> Executing");
   2843                 m_state = OMX_StateExecuting;
   2844                 bFlag = 1;
   2845             }
   2846             /* Requesting transition from Pause to Idle */
   2847             else if (eState == OMX_StateIdle) {
   2848                 /* Since error is None , we will post an event
   2849                    at the end of this function definition */
   2850                 DEBUG_PRINT_LOW("Pause --> Idle");
   2851                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2852                 if (!sem_posted) {
   2853                     sem_posted = 1;
   2854                     sem_post (&m_cmd_lock);
   2855                     execute_omx_flush(OMX_ALL);
   2856                 }
   2857                 bFlag = 0;
   2858             }
   2859             /* Requesting transition from Pause to loaded */
   2860             else if (eState == OMX_StateLoaded) {
   2861                 DEBUG_PRINT_ERROR("Pause --> loaded");
   2862                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2863                         OMX_COMPONENT_GENERATE_EVENT);
   2864                 eRet = OMX_ErrorIncorrectStateTransition;
   2865             }
   2866             /* Requesting transition from Pause to WaitForResources */
   2867             else if (eState == OMX_StateWaitForResources) {
   2868                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
   2869                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2870                         OMX_COMPONENT_GENERATE_EVENT);
   2871                 eRet = OMX_ErrorIncorrectStateTransition;
   2872             }
   2873             /* Requesting transition from Pause to Pause */
   2874             else if (eState == OMX_StatePause) {
   2875                 DEBUG_PRINT_ERROR("Pause --> Pause");
   2876                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2877                         OMX_COMPONENT_GENERATE_EVENT);
   2878                 eRet = OMX_ErrorSameState;
   2879             }
   2880             /* Requesting transition from Pause to Invalid */
   2881             else if (eState == OMX_StateInvalid) {
   2882                 DEBUG_PRINT_ERROR("Pause --> Invalid");
   2883                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2884                 eRet = OMX_ErrorInvalidState;
   2885             } else {
   2886                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
   2887                 eRet = OMX_ErrorBadParameter;
   2888             }
   2889         }
   2890         /***************************/
   2891         /* Current State is WaitForResources  */
   2892         /***************************/
   2893         else if (m_state == OMX_StateWaitForResources) {
   2894             /* Requesting transition from WaitForResources to Loaded */
   2895             if (eState == OMX_StateLoaded) {
   2896                 /* Since error is None , we will post an event
   2897                    at the end of this function definition */
   2898                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
   2899             }
   2900             /* Requesting transition from WaitForResources to WaitForResources */
   2901             else if (eState == OMX_StateWaitForResources) {
   2902                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
   2903                 post_event(OMX_EventError,OMX_ErrorSameState,
   2904                         OMX_COMPONENT_GENERATE_EVENT);
   2905                 eRet = OMX_ErrorSameState;
   2906             }
   2907             /* Requesting transition from WaitForResources to Executing */
   2908             else if (eState == OMX_StateExecuting) {
   2909                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
   2910                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2911                         OMX_COMPONENT_GENERATE_EVENT);
   2912                 eRet = OMX_ErrorIncorrectStateTransition;
   2913             }
   2914             /* Requesting transition from WaitForResources to Pause */
   2915             else if (eState == OMX_StatePause) {
   2916                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
   2917                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2918                         OMX_COMPONENT_GENERATE_EVENT);
   2919                 eRet = OMX_ErrorIncorrectStateTransition;
   2920             }
   2921             /* Requesting transition from WaitForResources to Invalid */
   2922             else if (eState == OMX_StateInvalid) {
   2923                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
   2924                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2925                 eRet = OMX_ErrorInvalidState;
   2926             }
   2927             /* Requesting transition from WaitForResources to Loaded -
   2928                is NOT tested by Khronos TS */
   2929 
   2930         } else {
   2931             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
   2932             eRet = OMX_ErrorBadParameter;
   2933         }
   2934     }
   2935     /********************************/
   2936     /* Current State is Invalid */
   2937     /*******************************/
   2938     else if (m_state == OMX_StateInvalid) {
   2939         /* State Transition from Inavlid to any state */
   2940         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   2941                     || OMX_StateIdle || OMX_StateExecuting
   2942                     || OMX_StatePause || OMX_StateInvalid)) {
   2943             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
   2944             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   2945                     OMX_COMPONENT_GENERATE_EVENT);
   2946             eRet = OMX_ErrorInvalidState;
   2947         }
   2948     } else if (cmd == OMX_CommandFlush) {
   2949         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
   2950                 "with param1: %u", (unsigned int)param1);
   2951 #ifdef _MSM8974_
   2952         send_codec_config();
   2953 #endif
   2954         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
   2955                     param1 == OMX_ALL)) {
   2956             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
   2957                struct timespec ts;
   2958 
   2959                clock_gettime(CLOCK_REALTIME, &ts);
   2960                ts.tv_sec += 2;
   2961                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
   2962                        m_queued_codec_config_count);
   2963                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
   2964                if (sem_timedwait(&m_safe_flush, &ts)) {
   2965                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
   2966                }
   2967                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
   2968             }
   2969         }
   2970 
   2971         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2972             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   2973         }
   2974         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2975             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   2976         }
   2977         if (!sem_posted) {
   2978             sem_posted = 1;
   2979             DEBUG_PRINT_LOW("Set the Semaphore");
   2980             sem_post (&m_cmd_lock);
   2981             execute_omx_flush(param1);
   2982         }
   2983         bFlag = 0;
   2984     } else if ( cmd == OMX_CommandPortEnable) {
   2985         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
   2986                 "with param1: %u", (unsigned int)param1);
   2987         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2988             m_inp_bEnabled = OMX_TRUE;
   2989 
   2990             if ( (m_state == OMX_StateLoaded &&
   2991                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2992                     || allocate_input_done()) {
   2993                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   2994                         OMX_COMPONENT_GENERATE_EVENT);
   2995             } else {
   2996                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   2997                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2998                 // Skip the event notification
   2999                 bFlag = 0;
   3000             }
   3001         }
   3002         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3003             DEBUG_PRINT_LOW("Enable output Port command recieved");
   3004             m_out_bEnabled = OMX_TRUE;
   3005 
   3006             if ( (m_state == OMX_StateLoaded &&
   3007                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3008                     || (allocate_output_done())) {
   3009                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   3010                         OMX_COMPONENT_GENERATE_EVENT);
   3011 
   3012             } else {
   3013                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3014                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3015                 // Skip the event notification
   3016                 bFlag = 0;
   3017                 /* enable/disable downscaling if required */
   3018                 ret = decide_downscalar();
   3019                 if (ret) {
   3020                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
   3021                 }
   3022             }
   3023         }
   3024     } else if (cmd == OMX_CommandPortDisable) {
   3025         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
   3026                 "with param1: %u", (unsigned int)param1);
   3027         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3028             codec_config_flag = false;
   3029             m_inp_bEnabled = OMX_FALSE;
   3030             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3031                     && release_input_done()) {
   3032                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   3033                         OMX_COMPONENT_GENERATE_EVENT);
   3034             } else {
   3035                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3036                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3037                     if (!sem_posted) {
   3038                         sem_posted = 1;
   3039                         sem_post (&m_cmd_lock);
   3040                     }
   3041                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   3042                 }
   3043 
   3044                 // Skip the event notification
   3045                 bFlag = 0;
   3046             }
   3047         }
   3048         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3049             m_out_bEnabled = OMX_FALSE;
   3050             DEBUG_PRINT_LOW("Disable output Port command recieved");
   3051             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3052                     && release_output_done()) {
   3053                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   3054                         OMX_COMPONENT_GENERATE_EVENT);
   3055             } else {
   3056                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3057                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3058                     if (!sem_posted) {
   3059                         sem_posted = 1;
   3060                         sem_post (&m_cmd_lock);
   3061                     }
   3062                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   3063                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   3064                 }
   3065                 // Skip the event notification
   3066                 bFlag = 0;
   3067 
   3068             }
   3069         }
   3070     } else {
   3071         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
   3072         eRet = OMX_ErrorNotImplemented;
   3073     }
   3074     if (eRet == OMX_ErrorNone && bFlag) {
   3075         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   3076     }
   3077     if (!sem_posted) {
   3078         sem_post(&m_cmd_lock);
   3079     }
   3080 
   3081     return eRet;
   3082 }
   3083 
   3084 /* ======================================================================
   3085    FUNCTION
   3086    omx_vdec::ExecuteOmxFlush
   3087 
   3088    DESCRIPTION
   3089    Executes the OMX flush.
   3090 
   3091    PARAMETERS
   3092    flushtype - input flush(1)/output flush(0)/ both.
   3093 
   3094    RETURN VALUE
   3095    true/false
   3096 
   3097    ========================================================================== */
   3098 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   3099 {
   3100     bool bRet = false;
   3101     struct v4l2_plane plane;
   3102     struct v4l2_buffer v4l2_buf;
   3103     struct v4l2_decoder_cmd dec;
   3104     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
   3105     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   3106     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   3107 
   3108     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   3109 
   3110     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   3111         output_flush_progress = true;
   3112         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3113     } else {
   3114         /* XXX: The driver/hardware does not support flushing of individual ports
   3115          * in all states. So we pretty much need to flush both ports internally,
   3116          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   3117          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   3118          * we automatically omit sending the FLUSH done for the "opposite" port. */
   3119         input_flush_progress = true;
   3120         output_flush_progress = true;
   3121         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3122         request_perf_level(VIDC_TURBO);
   3123     }
   3124 
   3125     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   3126         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
   3127         bRet = false;
   3128     }
   3129 
   3130     return bRet;
   3131 }
   3132 /*=========================================================================
   3133 FUNCTION : execute_output_flush
   3134 
   3135 DESCRIPTION
   3136 Executes the OMX flush at OUTPUT PORT.
   3137 
   3138 PARAMETERS
   3139 None.
   3140 
   3141 RETURN VALUE
   3142 true/false
   3143 ==========================================================================*/
   3144 bool omx_vdec::execute_output_flush()
   3145 {
   3146     unsigned long p1 = 0; // Parameter - 1
   3147     unsigned long p2 = 0; // Parameter - 2
   3148     unsigned long ident = 0;
   3149     bool bRet = true;
   3150 
   3151     /*Generate FBD for all Buffers in the FTBq*/
   3152     pthread_mutex_lock(&m_lock);
   3153     DEBUG_PRINT_LOW("Initiate Output Flush");
   3154 
   3155     //reset last render TS
   3156     if(m_last_rendered_TS > 0) {
   3157         m_last_rendered_TS = 0;
   3158     }
   3159 
   3160     while (m_ftb_q.m_size) {
   3161         DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
   3162                 m_ftb_q.m_size,pending_output_buffers);
   3163         m_ftb_q.pop_entry(&p1,&p2,&ident);
   3164         DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
   3165         if (ident == m_fill_output_msg ) {
   3166             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
   3167         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   3168             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
   3169         }
   3170     }
   3171     pthread_mutex_unlock(&m_lock);
   3172     output_flush_progress = false;
   3173 
   3174     if (arbitrary_bytes) {
   3175         prev_ts = LLONG_MAX;
   3176         rst_prev_ts = true;
   3177     }
   3178     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   3179     return bRet;
   3180 }
   3181 /*=========================================================================
   3182 FUNCTION : execute_input_flush
   3183 
   3184 DESCRIPTION
   3185 Executes the OMX flush at INPUT PORT.
   3186 
   3187 PARAMETERS
   3188 None.
   3189 
   3190 RETURN VALUE
   3191 true/false
   3192 ==========================================================================*/
   3193 bool omx_vdec::execute_input_flush()
   3194 {
   3195     unsigned       i =0;
   3196     unsigned long p1 = 0; // Parameter - 1
   3197     unsigned long p2 = 0; // Parameter - 2
   3198     unsigned long ident = 0;
   3199     bool bRet = true;
   3200 
   3201     /*Generate EBD for all Buffers in the ETBq*/
   3202     DEBUG_PRINT_LOW("Initiate Input Flush");
   3203 
   3204     pthread_mutex_lock(&m_lock);
   3205     DEBUG_PRINT_LOW("Check if the Queue is empty");
   3206     while (m_etb_q.m_size) {
   3207         m_etb_q.pop_entry(&p1,&p2,&ident);
   3208 
   3209         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   3210             DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   3211             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   3212         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   3213             pending_input_buffers++;
   3214             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   3215                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   3216             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   3217         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   3218             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   3219                     (OMX_BUFFERHEADERTYPE *)p1);
   3220             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   3221         }
   3222     }
   3223     time_stamp_dts.flush_timestamp();
   3224     /*Check if Heap Buffers are to be flushed*/
   3225     if (arbitrary_bytes && !(codec_config_flag)) {
   3226         DEBUG_PRINT_LOW("Reset all the variables before flusing");
   3227         h264_scratch.nFilledLen = 0;
   3228         nal_count = 0;
   3229         look_ahead_nal = false;
   3230         frame_count = 0;
   3231         h264_last_au_ts = LLONG_MAX;
   3232         h264_last_au_flags = 0;
   3233         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   3234         m_demux_entries = 0;
   3235         DEBUG_PRINT_LOW("Initialize parser");
   3236         if (m_frame_parser.mutils) {
   3237             m_frame_parser.mutils->initialize_frame_checking_environment();
   3238         }
   3239 
   3240         while (m_input_pending_q.m_size) {
   3241             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   3242             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   3243         }
   3244 
   3245         if (psource_frame) {
   3246             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   3247             psource_frame = NULL;
   3248         }
   3249 
   3250         if (pdest_frame) {
   3251             pdest_frame->nFilledLen = 0;
   3252             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
   3253                     (unsigned int)NULL);
   3254             pdest_frame = NULL;
   3255         }
   3256         m_frame_parser.flush();
   3257     } else if (codec_config_flag) {
   3258         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   3259                 "is not sent to the driver yet");
   3260     }
   3261     pthread_mutex_unlock(&m_lock);
   3262     input_flush_progress = false;
   3263     if (!arbitrary_bytes) {
   3264         prev_ts = LLONG_MAX;
   3265         rst_prev_ts = true;
   3266     }
   3267 #ifdef _ANDROID_
   3268     if (m_debug_timestamp) {
   3269         m_timestamp_list.reset_ts_list();
   3270     }
   3271 #endif
   3272     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   3273     return bRet;
   3274 }
   3275 
   3276 
   3277 /* ======================================================================
   3278    FUNCTION
   3279    omx_vdec::SendCommandEvent
   3280 
   3281    DESCRIPTION
   3282    Send the event to decoder pipe.  This is needed to generate the callbacks
   3283    in decoder thread context.
   3284 
   3285    PARAMETERS
   3286    None.
   3287 
   3288    RETURN VALUE
   3289    true/false
   3290 
   3291    ========================================================================== */
   3292 bool omx_vdec::post_event(unsigned long p1,
   3293         unsigned long p2,
   3294         unsigned long id)
   3295 {
   3296     bool bRet = false;
   3297 
   3298     /* Just drop messages typically generated by hardware (w/o client request),
   3299      * if we've reported an error to client. */
   3300     if (m_error_propogated) {
   3301         switch (id) {
   3302             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   3303             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   3304                 DEBUG_PRINT_ERROR("Dropping message %lx "
   3305                         "since client expected to be in error state", id);
   3306                 return false;
   3307             default:
   3308                 /* whatever */
   3309                 break;
   3310         }
   3311     }
   3312 
   3313     pthread_mutex_lock(&m_lock);
   3314 
   3315     if (id == m_fill_output_msg ||
   3316             id == OMX_COMPONENT_GENERATE_FBD ||
   3317             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
   3318             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
   3319         m_ftb_q.insert_entry(p1,p2,id);
   3320     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   3321             id == OMX_COMPONENT_GENERATE_EBD ||
   3322             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
   3323             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
   3324         m_etb_q.insert_entry(p1,p2,id);
   3325     } else {
   3326         m_cmd_q.insert_entry(p1,p2,id);
   3327     }
   3328 
   3329     bRet = true;
   3330     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   3331     post_message(this, id);
   3332 
   3333     pthread_mutex_unlock(&m_lock);
   3334 
   3335     return bRet;
   3336 }
   3337 
   3338 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   3339 {
   3340     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3341     if (!profileLevelType)
   3342         return OMX_ErrorBadParameter;
   3343 
   3344     if (profileLevelType->nPortIndex == 0) {
   3345         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3346             if (profileLevelType->nProfileIndex == 0) {
   3347                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3348                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3349 
   3350             } else if (profileLevelType->nProfileIndex == 1) {
   3351                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   3352                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3353             } else if (profileLevelType->nProfileIndex == 2) {
   3354                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   3355                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3356             } else {
   3357                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3358                         (unsigned int)profileLevelType->nProfileIndex);
   3359                 eRet = OMX_ErrorNoMore;
   3360             }
   3361         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3362             if (profileLevelType->nProfileIndex == 0) {
   3363                 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
   3364                 profileLevelType->eLevel   = QOMX_VIDEO_MVCLevel51;
   3365             } else {
   3366                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3367                                 (unsigned int)profileLevelType->nProfileIndex);
   3368                 eRet = OMX_ErrorNoMore;
   3369             }
   3370         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3371             if (profileLevelType->nProfileIndex == 0) {
   3372                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
   3373                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3374             } else if (profileLevelType->nProfileIndex == 1) {
   3375                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
   3376                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3377             } else {
   3378                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3379                         (unsigned int)profileLevelType->nProfileIndex);
   3380                 eRet = OMX_ErrorNoMore;
   3381             }
   3382         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   3383             if (profileLevelType->nProfileIndex == 0) {
   3384                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   3385                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   3386             } else {
   3387                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3388                                 (unsigned int)profileLevelType->nProfileIndex);
   3389                 eRet = OMX_ErrorNoMore;
   3390             }
   3391         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3392             if (profileLevelType->nProfileIndex == 0) {
   3393                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   3394                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3395             } else if (profileLevelType->nProfileIndex == 1) {
   3396                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   3397                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3398             } else {
   3399                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3400                                 (unsigned int)profileLevelType->nProfileIndex);
   3401                 eRet = OMX_ErrorNoMore;
   3402             }
   3403         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3404                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   3405             eRet = OMX_ErrorNoMore;
   3406         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3407             if (profileLevelType->nProfileIndex == 0) {
   3408                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   3409                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3410             } else if (profileLevelType->nProfileIndex == 1) {
   3411                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   3412                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3413             } else {
   3414                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3415                                 (unsigned int)profileLevelType->nProfileIndex);
   3416                 eRet = OMX_ErrorNoMore;
   3417             }
   3418         } else {
   3419             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
   3420             eRet = OMX_ErrorNoMore;
   3421         }
   3422     } else {
   3423         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
   3424                           (unsigned int)profileLevelType->nPortIndex);
   3425         eRet = OMX_ErrorBadPortIndex;
   3426     }
   3427     return eRet;
   3428 }
   3429 
   3430 /* ======================================================================
   3431    FUNCTION
   3432    omx_vdec::GetParameter
   3433 
   3434    DESCRIPTION
   3435    OMX Get Parameter method implementation
   3436 
   3437    PARAMETERS
   3438    <TBD>.
   3439 
   3440    RETURN VALUE
   3441    Error None if successful.
   3442 
   3443    ========================================================================== */
   3444 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3445         OMX_IN OMX_INDEXTYPE paramIndex,
   3446         OMX_INOUT OMX_PTR     paramData)
   3447 {
   3448     (void) hComp;
   3449     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3450 
   3451     DEBUG_PRINT_LOW("get_parameter:");
   3452     if (m_state == OMX_StateInvalid) {
   3453         DEBUG_PRINT_ERROR("Get Param in Invalid State");
   3454         return OMX_ErrorInvalidState;
   3455     }
   3456     if (paramData == NULL) {
   3457         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
   3458         return OMX_ErrorBadParameter;
   3459     }
   3460     switch ((unsigned long)paramIndex) {
   3461         case OMX_IndexParamPortDefinition: {
   3462                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3463                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   3464                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3465                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   3466                                decide_dpb_buffer_mode(is_down_scalar_enabled);
   3467                                eRet = update_portdef(portDefn);
   3468                                if (eRet == OMX_ErrorNone)
   3469                                    m_port_def = *portDefn;
   3470                                break;
   3471                            }
   3472         case OMX_IndexParamVideoInit: {
   3473                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3474                               OMX_PORT_PARAM_TYPE *portParamType =
   3475                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3476                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   3477 
   3478                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3479                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3480                               portParamType->nPorts           = 2;
   3481                               portParamType->nStartPortNumber = 0;
   3482                               break;
   3483                           }
   3484         case OMX_IndexParamVideoPortFormat: {
   3485                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3486                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3487                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3488                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   3489 
   3490                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   3491                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3492 
   3493                                 if (0 == portFmt->nPortIndex) {
   3494                                     if (0 == portFmt->nIndex) {
   3495                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   3496                                         portFmt->eCompressionFormat = eCompressionFormat;
   3497                                     } else {
   3498                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3499                                                 " NoMore compression formats");
   3500                                         eRet =  OMX_ErrorNoMore;
   3501                                     }
   3502                                 } else if (1 == portFmt->nPortIndex) {
   3503                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   3504 
   3505                                     // Distinguish non-surface mode from normal playback use-case based on
   3506                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
   3507                                     // For non-android, use the default list
   3508                                     // Also use default format-list if FLEXIBLE YUV is supported,
   3509                                     // as the client negotiates the standard color-format if it needs to
   3510                                     bool useNonSurfaceMode = false;
   3511 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
   3512                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
   3513 #endif
   3514                                     if (is_thulium_v1) {
   3515                                         portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3516                                     } else {
   3517                                         portFmt->eColorFormat = useNonSurfaceMode ?
   3518                                             getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
   3519                                             getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3520                                     }
   3521 
   3522                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
   3523                                         eRet = OMX_ErrorNoMore;
   3524                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3525                                                 " NoMore Color formats");
   3526                                     }
   3527                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
   3528                                 } else {
   3529                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   3530                                             (int)portFmt->nPortIndex);
   3531                                     eRet = OMX_ErrorBadPortIndex;
   3532                                 }
   3533                                 break;
   3534                             }
   3535                             /*Component should support this port definition*/
   3536         case OMX_IndexParamAudioInit: {
   3537                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3538                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   3539                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3540                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   3541                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3542                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3543                               audioPortParamType->nPorts           = 0;
   3544                               audioPortParamType->nStartPortNumber = 0;
   3545                               break;
   3546                           }
   3547                           /*Component should support this port definition*/
   3548         case OMX_IndexParamImageInit: {
   3549                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3550                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   3551                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3552                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   3553                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3554                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3555                               imagePortParamType->nPorts           = 0;
   3556                               imagePortParamType->nStartPortNumber = 0;
   3557                               break;
   3558 
   3559                           }
   3560                           /*Component should support this port definition*/
   3561         case OMX_IndexParamOtherInit: {
   3562                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
   3563                                       paramIndex);
   3564                               eRet =OMX_ErrorUnsupportedIndex;
   3565                               break;
   3566                           }
   3567         case OMX_IndexParamStandardComponentRole: {
   3568                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   3569                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3570                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3571                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   3572                                   comp_role->nSize = sizeof(*comp_role);
   3573 
   3574                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
   3575                                           paramIndex);
   3576                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   3577                                           OMX_MAX_STRINGNAME_SIZE);
   3578                                   break;
   3579                               }
   3580                               /* Added for parameter test */
   3581         case OMX_IndexParamPriorityMgmt: {
   3582                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   3583                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   3584                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   3585                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   3586                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   3587                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
   3588 
   3589                              break;
   3590                          }
   3591                          /* Added for parameter test */
   3592         case OMX_IndexParamCompBufferSupplier: {
   3593                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   3594                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   3595                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3596                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   3597 
   3598                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
   3599                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   3600                                    if (0 == bufferSupplierType->nPortIndex)
   3601                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3602                                    else if (1 == bufferSupplierType->nPortIndex)
   3603                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3604                                    else
   3605                                        eRet = OMX_ErrorBadPortIndex;
   3606 
   3607 
   3608                                    break;
   3609                                }
   3610         case OMX_IndexParamVideoAvc: {
   3611                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
   3612                                      paramIndex);
   3613                              break;
   3614                          }
   3615         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3616                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
   3617                                      paramIndex);
   3618                              break;
   3619                          }
   3620         case OMX_IndexParamVideoH263: {
   3621                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   3622                                       paramIndex);
   3623                               break;
   3624                           }
   3625         case OMX_IndexParamVideoMpeg4: {
   3626                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   3627                                        paramIndex);
   3628                                break;
   3629                            }
   3630         case OMX_IndexParamVideoMpeg2: {
   3631                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   3632                                        paramIndex);
   3633                                break;
   3634                            }
   3635         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   3636                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3637                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
   3638                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   3639                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   3640                                         eRet = get_supported_profile_level(profileLevelType);
   3641                                         break;
   3642                                     }
   3643 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3644         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   3645                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
   3646                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   3647                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   3648                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3649 
   3650                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
   3651                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   3652                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   3653                                             } else {
   3654                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
   3655                                             }
   3656                                         } else {
   3657                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   3658                                             eRet = OMX_ErrorBadParameter;
   3659                                         }
   3660                                     }
   3661                                     break;
   3662 #endif
   3663 
   3664 #ifdef FLEXYUV_SUPPORTED
   3665         case OMX_QcomIndexFlexibleYUVDescription: {
   3666                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
   3667                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
   3668                 eRet = describeColorFormat(paramData);
   3669                 break;
   3670             }
   3671 #endif
   3672         case OMX_IndexParamVideoProfileLevelCurrent: {
   3673              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3674              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3675              struct v4l2_control profile_control, level_control;
   3676 
   3677              switch (drv_ctx.decoder_format) {
   3678                  case VDEC_CODECTYPE_H264:
   3679                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   3680                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   3681                      break;
   3682                  default:
   3683                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
   3684                      eRet = OMX_ErrorNotImplemented;
   3685                      break;
   3686              }
   3687 
   3688              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
   3689                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
   3690                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   3691                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   3692                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3693                         break;
   3694                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   3695                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
   3696                         break;
   3697                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   3698                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
   3699                         break;
   3700                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   3701                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
   3702                         break;
   3703                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   3704                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
   3705                         break;
   3706                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   3707                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
   3708                         break;
   3709                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   3710                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
   3711                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
   3712                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
   3713                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
   3714                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
   3715                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
   3716                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
   3717                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
   3718                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
   3719                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   3720                         eRet = OMX_ErrorUnsupportedIndex;
   3721                         break;
   3722                 }
   3723              } else {
   3724                  eRet = OMX_ErrorUnsupportedIndex;
   3725              }
   3726 
   3727 
   3728              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
   3729                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
   3730                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   3731                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
   3732                         break;
   3733                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   3734                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
   3735                         break;
   3736                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   3737                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
   3738                         break;
   3739                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   3740                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
   3741                         break;
   3742                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   3743                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
   3744                         break;
   3745                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   3746                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
   3747                         break;
   3748                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   3749                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
   3750                         break;
   3751                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   3752                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
   3753                         break;
   3754                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   3755                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
   3756                         break;
   3757                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   3758                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
   3759                         break;
   3760                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   3761                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
   3762                         break;
   3763                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   3764                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
   3765                         break;
   3766                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   3767                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
   3768                         break;
   3769                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   3770                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
   3771                         break;
   3772                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   3773                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
   3774                         break;
   3775                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   3776                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
   3777                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   3778                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
   3779                         break;
   3780                 }
   3781              } else {
   3782                  eRet = OMX_ErrorUnsupportedIndex;
   3783              }
   3784 
   3785              break;
   3786 
   3787          }
   3788         default: {
   3789                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
   3790                  eRet =OMX_ErrorUnsupportedIndex;
   3791              }
   3792 
   3793     }
   3794 
   3795     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
   3796             drv_ctx.video_resolution.frame_width,
   3797             drv_ctx.video_resolution.frame_height,
   3798             drv_ctx.video_resolution.stride,
   3799             drv_ctx.video_resolution.scan_lines);
   3800 
   3801     return eRet;
   3802 }
   3803 
   3804 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3805 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   3806 {
   3807     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   3808     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3809     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   3810 
   3811     if ((params == NULL) ||
   3812             (params->nativeBuffer == NULL) ||
   3813             (params->nativeBuffer->handle == NULL) ||
   3814             !m_enable_android_native_buffers)
   3815         return OMX_ErrorBadParameter;
   3816     m_use_android_native_buffers = OMX_TRUE;
   3817     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   3818     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   3819     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   3820         OMX_U8 *buffer = NULL;
   3821         if (!secure_mode) {
   3822             buffer = (OMX_U8*)mmap(0, handle->size,
   3823                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   3824             if (buffer == MAP_FAILED) {
   3825                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   3826                 return OMX_ErrorInsufficientResources;
   3827             }
   3828         }
   3829         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   3830     } else {
   3831         eRet = OMX_ErrorBadParameter;
   3832     }
   3833     return eRet;
   3834 }
   3835 #endif
   3836 
   3837 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
   3838     struct v4l2_control control;
   3839     struct v4l2_format fmt;
   3840     control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   3841     control.value = 1;
   3842     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3843     if (rc < 0) {
   3844         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   3845         return OMX_ErrorHardware;
   3846     }
   3847     m_smoothstreaming_mode = true;
   3848     return OMX_ErrorNone;
   3849 }
   3850 
   3851 /* ======================================================================
   3852    FUNCTION
   3853    omx_vdec::Setparameter
   3854 
   3855    DESCRIPTION
   3856    OMX Set Parameter method implementation.
   3857 
   3858    PARAMETERS
   3859    <TBD>.
   3860 
   3861    RETURN VALUE
   3862    OMX Error None if successful.
   3863 
   3864    ========================================================================== */
   3865 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3866         OMX_IN OMX_INDEXTYPE paramIndex,
   3867         OMX_IN OMX_PTR        paramData)
   3868 {
   3869     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3870     int ret=0;
   3871     struct v4l2_format fmt;
   3872 #ifdef _ANDROID_
   3873     char property_value[PROPERTY_VALUE_MAX] = {0};
   3874 #endif
   3875     if (m_state == OMX_StateInvalid) {
   3876         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3877         return OMX_ErrorInvalidState;
   3878     }
   3879     if (paramData == NULL) {
   3880         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   3881         return OMX_ErrorBadParameter;
   3882     }
   3883     if ((m_state != OMX_StateLoaded) &&
   3884             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   3885             (m_out_bEnabled == OMX_TRUE) &&
   3886             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   3887             (m_inp_bEnabled == OMX_TRUE)) {
   3888         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3889         return OMX_ErrorIncorrectStateOperation;
   3890     }
   3891     switch ((unsigned long)paramIndex) {
   3892         case OMX_IndexParamPortDefinition: {
   3893                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3894                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   3895                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3896                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   3897                                //been called.
   3898                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
   3899                                        (int)portDefn->format.video.nFrameHeight,
   3900                                        (int)portDefn->format.video.nFrameWidth);
   3901 
   3902                                if (portDefn->nBufferCountActual >= MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   3903                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
   3904                                                           portDefn->nBufferCountActual);
   3905                                    eRet = OMX_ErrorBadParameter;
   3906                                    break;
   3907                                }
   3908                                if (OMX_DirOutput == portDefn->eDir) {
   3909                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
   3910                                    bool port_format_changed = false;
   3911                                    m_display_id = portDefn->format.video.pNativeWindow;
   3912                                    unsigned int buffer_size;
   3913                                    /* update output port resolution with client supplied dimensions
   3914                                       in case scaling is enabled, else it follows input resolution set
   3915                                    */
   3916                                    decide_dpb_buffer_mode(is_down_scalar_enabled);
   3917                                    if (is_down_scalar_enabled) {
   3918                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
   3919                                                (unsigned int)portDefn->format.video.nFrameWidth,
   3920                                                (unsigned int)portDefn->format.video.nFrameHeight);
   3921                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   3922                                                portDefn->format.video.nFrameWidth != 0x0) {
   3923                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3924                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3925                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3926                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   3927                                            if (ret) {
   3928                                                DEBUG_PRINT_ERROR("Get Resolution failed");
   3929                                                eRet = OMX_ErrorHardware;
   3930                                                break;
   3931                                            }
   3932                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
   3933                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
   3934                                                    port_format_changed = true;
   3935                                            }
   3936                                            update_resolution(portDefn->format.video.nFrameWidth,
   3937                                                    portDefn->format.video.nFrameHeight,
   3938                                                    portDefn->format.video.nFrameWidth,
   3939                                                    portDefn->format.video.nFrameHeight);
   3940 
   3941                                            /* set crop info */
   3942                                            rectangle.nLeft = 0;
   3943                                            rectangle.nTop = 0;
   3944                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
   3945                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
   3946 
   3947                                            eRet = is_video_session_supported();
   3948                                            if (eRet)
   3949                                                break;
   3950                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3951                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3952                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   3953                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   3954                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3955                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
   3956                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
   3957                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   3958                                            if (ret) {
   3959                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   3960                                                eRet = OMX_ErrorUnsupportedSetting;
   3961                                            } else
   3962                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   3963                                        }
   3964 
   3965                                        if (eRet) {
   3966                                            break;
   3967                                        }
   3968 
   3969                                        if (secure_mode) {
   3970                                            struct v4l2_control control;
   3971                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
   3972                                            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   3973                                                DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
   3974                                                eRet = OMX_ErrorHardware;
   3975                                            } else {
   3976                                                /* This is a workaround for a bug in fw which uses stride
   3977                                                 * and slice instead of width and height to check against
   3978                                                 * the threshold.
   3979                                                 */
   3980                                                OMX_U32 stride, slice;
   3981                                                if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   3982                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
   3983                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
   3984                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   3985                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth);
   3986                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight);
   3987                                                } else {
   3988                                                    stride = portDefn->format.video.nFrameWidth;
   3989                                                    slice = portDefn->format.video.nFrameHeight;
   3990                                                }
   3991 
   3992                                                DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
   3993                                                DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
   3994 
   3995                                                if (stride * slice <= (OMX_U32)control.value) {
   3996                                                    secure_scaling_to_non_secure_opb = true;
   3997                                                    DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
   3998                                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
   3999                                                    control.value = 1;
   4000                                                    if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   4001                                                        DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
   4002                                                        eRet = OMX_ErrorUnsupportedSetting;
   4003                                                    }
   4004                                                }
   4005                                            }
   4006                                        }
   4007                                    }
   4008 
   4009                                    if (eRet) {
   4010                                        break;
   4011                                    }
   4012 
   4013                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4014                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
   4015                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4016                                        eRet = OMX_ErrorBadParameter;
   4017                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
   4018                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
   4019                                        eRet = OMX_ErrorBadParameter;
   4020                                    } else if (!port_format_changed) {
   4021 
   4022                                        // Buffer count can change only when port is disabled
   4023                                        if (!release_output_done()) {
   4024                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
   4025                                            eRet = OMX_ErrorInvalidState;
   4026                                            break;
   4027                                        }
   4028 
   4029                                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
   4030                                                portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size ) {
   4031                                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
   4032                                            drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
   4033                                            drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
   4034                                            drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
   4035                                                drv_ctx.extradata_info.buffer_size;
   4036                                            eRet = set_buffer_req(&drv_ctx.op_buf);
   4037                                            if (eRet == OMX_ErrorNone)
   4038                                                m_port_def = *portDefn;
   4039                                        } else {
   4040                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
   4041                                                    drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size,
   4042                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4043                                            eRet = OMX_ErrorBadParameter;
   4044                                        }
   4045                                    }
   4046                                } else if (OMX_DirInput == portDefn->eDir) {
   4047                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
   4048                                    bool port_format_changed = false;
   4049                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   4050                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   4051                                        // Frame rate only should be set if this is a "known value" or to
   4052                                        // activate ts prediction logic (arbitrary mode only) sending input
   4053                                        // timestamps with max value (LLONG_MAX).
   4054                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
   4055                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
   4056                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   4057                                                drv_ctx.frame_rate.fps_denominator);
   4058                                        if (!drv_ctx.frame_rate.fps_numerator) {
   4059                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   4060                                            drv_ctx.frame_rate.fps_numerator = 30;
   4061                                        }
   4062                                        if (drv_ctx.frame_rate.fps_denominator)
   4063                                            drv_ctx.frame_rate.fps_numerator = (int)
   4064                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   4065                                        drv_ctx.frame_rate.fps_denominator = 1;
   4066                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   4067                                            drv_ctx.frame_rate.fps_numerator;
   4068                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
   4069                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   4070                                                (float)drv_ctx.frame_rate.fps_denominator);
   4071 
   4072                                        struct v4l2_outputparm oparm;
   4073                                        /*XXX: we're providing timing info as seconds per frame rather than frames
   4074                                         * per second.*/
   4075                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   4076                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   4077 
   4078                                        struct v4l2_streamparm sparm;
   4079                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4080                                        sparm.parm.output = oparm;
   4081                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   4082                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
   4083                                            eRet = OMX_ErrorHardware;
   4084                                            break;
   4085                                        }
   4086                                        m_perf_control.request_cores(frm_int);
   4087                                    }
   4088 
   4089                                    if (drv_ctx.video_resolution.frame_height !=
   4090                                            portDefn->format.video.nFrameHeight ||
   4091                                            drv_ctx.video_resolution.frame_width  !=
   4092                                            portDefn->format.video.nFrameWidth) {
   4093                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
   4094                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4095                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4096                                        port_format_changed = true;
   4097                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
   4098                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
   4099                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
   4100                                            if (m_smoothstreaming_mode &&
   4101                                                    ((frameWidth * frameHeight) <
   4102                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
   4103                                                frameWidth = m_smoothstreaming_width;
   4104                                                frameHeight = m_smoothstreaming_height;
   4105                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
   4106                                                        "for adaptive-playback/smooth-streaming",
   4107                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
   4108                                            }
   4109                                            update_resolution(frameWidth, frameHeight,
   4110                                                    frameWidth, frameHeight);
   4111                                            eRet = is_video_session_supported();
   4112                                            if (eRet)
   4113                                                break;
   4114                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4115                                            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4116                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4117                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4118                                            fmt.fmt.pix_mp.pixelformat = output_capability;
   4119                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4120                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4121                                            if (ret) {
   4122                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4123                                                eRet = OMX_ErrorUnsupportedSetting;
   4124                                            } else {
   4125                                                if (!is_down_scalar_enabled)
   4126                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
   4127                                            }
   4128                                        }
   4129                                    }
   4130                                    if (m_custom_buffersize.input_buffersize
   4131                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
   4132                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
   4133                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
   4134                                        eRet = OMX_ErrorBadParameter;
   4135                                        break;
   4136                                    }
   4137                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4138                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
   4139                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4140                                        eRet = OMX_ErrorBadParameter;
   4141                                        break;
   4142                                    }
   4143                                    // Buffer count can change only when port is disabled
   4144                                    if (!release_input_done()) {
   4145                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
   4146                                        eRet = OMX_ErrorInvalidState;
   4147                                        break;
   4148                                    }
   4149 
   4150                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   4151                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   4152                                        port_format_changed = true;
   4153                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   4154                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   4155                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   4156                                            (~(buffer_prop->alignment - 1));
   4157                                        eRet = set_buffer_req(buffer_prop);
   4158                                    }
   4159                                    if (false == port_format_changed) {
   4160                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
   4161                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
   4162                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4163                                        eRet = OMX_ErrorBadParameter;
   4164                                    }
   4165                                } else if (portDefn->eDir ==  OMX_DirMax) {
   4166                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   4167                                            (int)portDefn->nPortIndex);
   4168                                    eRet = OMX_ErrorBadPortIndex;
   4169                                }
   4170                            }
   4171                            break;
   4172         case OMX_IndexParamVideoPortFormat: {
   4173                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   4174                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   4175                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   4176                                 int ret=0;
   4177                                 struct v4l2_format fmt;
   4178                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
   4179                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
   4180 
   4181                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4182                                 if (1 == portFmt->nPortIndex) {
   4183                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4184                                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4185                                     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4186                                     enum vdec_output_fromat op_format;
   4187                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4188                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   4189                                             portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4190                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
   4191                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
   4192                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   4193                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   4194                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4195                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4196                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC;
   4197                                     } else
   4198                                         eRet = OMX_ErrorBadParameter;
   4199 
   4200                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4201                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4202                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   4203                                     } else {
   4204                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
   4205                                     }
   4206 
   4207                                     if (eRet == OMX_ErrorNone) {
   4208                                         drv_ctx.output_format = op_format;
   4209                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4210                                         if (ret) {
   4211                                             DEBUG_PRINT_ERROR("Set output format failed");
   4212                                             eRet = OMX_ErrorUnsupportedSetting;
   4213                                             /*TODO: How to handle this case */
   4214                                         } else {
   4215                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   4216                                         }
   4217                                     }
   4218                                     if (eRet == OMX_ErrorNone) {
   4219                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   4220                                             DEBUG_PRINT_ERROR("Set color format failed");
   4221                                             eRet = OMX_ErrorBadParameter;
   4222                                         }
   4223                                     }
   4224                                 }
   4225                             }
   4226                             break;
   4227 
   4228         case OMX_QcomIndexPortDefn: {
   4229                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
   4230                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   4231                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   4232                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
   4233                                     (unsigned int)portFmt->nFramePackingFormat);
   4234 
   4235                             /* Input port */
   4236                             if (portFmt->nPortIndex == 0) {
   4237                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   4238                                     if (secure_mode || m_input_pass_buffer_fd) {
   4239                                         arbitrary_bytes = false;
   4240                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
   4241                                         eRet = OMX_ErrorUnsupportedSetting;
   4242                                     } else {
   4243                                         arbitrary_bytes = true;
   4244                                     }
   4245                                 } else if (portFmt->nFramePackingFormat ==
   4246                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   4247                                     arbitrary_bytes = false;
   4248 #ifdef _ANDROID_
   4249                                     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   4250                                     if (atoi(property_value)) {
   4251                                         DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
   4252                                         arbitrary_bytes = true;
   4253                                     }
   4254 #endif
   4255                                 } else {
   4256                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
   4257                                             (unsigned int)portFmt->nFramePackingFormat);
   4258                                     eRet = OMX_ErrorUnsupportedSetting;
   4259                                 }
   4260                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4261                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
   4262                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   4263                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   4264                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   4265                                     m_out_mem_region_smi = OMX_TRUE;
   4266                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4267                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
   4268                                         m_use_output_pmem = OMX_TRUE;
   4269                                     }
   4270                                 }
   4271                             }
   4272                         }
   4273                         if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   4274                                     OMX_MAX_STRINGNAME_SIZE)) {
   4275                             arbitrary_bytes = true;
   4276                             DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264");
   4277                         }
   4278                         break;
   4279 
   4280         case OMX_IndexParamStandardComponentRole: {
   4281                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   4282                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   4283                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   4284                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
   4285                                           comp_role->cRole);
   4286 
   4287                                   if ((m_state == OMX_StateLoaded)&&
   4288                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
   4289                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   4290                                   } else {
   4291                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4292                                       return OMX_ErrorIncorrectStateOperation;
   4293                                   }
   4294 
   4295                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4296                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4297                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
   4298                                       } else {
   4299                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4300                                           eRet =OMX_ErrorUnsupportedSetting;
   4301                                       }
   4302                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4303                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4304                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   4305                                       } else {
   4306                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4307                                           eRet = OMX_ErrorUnsupportedSetting;
   4308                                       }
   4309                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4310                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4311                                           strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
   4312                                       } else {
   4313                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4314                                           eRet = OMX_ErrorUnsupportedSetting;
   4315                                       }
   4316                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4317                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4318                                           strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
   4319                                       } else {
   4320                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4321                                           eRet =OMX_ErrorUnsupportedSetting;
   4322                                       }
   4323                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4324                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4325                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
   4326                                       } else {
   4327                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4328                                           eRet = OMX_ErrorUnsupportedSetting;
   4329                                       }
   4330                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) ||
   4331                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
   4332                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
   4333                                         ) {
   4334                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) {
   4335                                           strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
   4336                                       } else {
   4337                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4338                                           eRet =OMX_ErrorUnsupportedSetting;
   4339                                       }
   4340                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) ||
   4341                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE))
   4342                                         ) {
   4343                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   4344                                           strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
   4345                                       } else {
   4346                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4347                                           eRet =OMX_ErrorUnsupportedSetting;
   4348                                       }
   4349                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   4350                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   4351                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4352                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
   4353                                       } else {
   4354                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4355                                           eRet = OMX_ErrorUnsupportedSetting;
   4356                                       }
   4357                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   4358                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
   4359                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4360                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
   4361                                       } else {
   4362                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4363                                           eRet = OMX_ErrorUnsupportedSetting;
   4364                                       }
   4365                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4366                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4367                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   4368                                       } else {
   4369                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4370                                           eRet = OMX_ErrorUnsupportedSetting;
   4371                                       }
   4372                                   } else {
   4373                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
   4374                                       eRet = OMX_ErrorInvalidComponentName;
   4375                                   }
   4376                                   break;
   4377                               }
   4378 
   4379         case OMX_IndexParamPriorityMgmt: {
   4380                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   4381                              if (m_state != OMX_StateLoaded) {
   4382                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4383                                  return OMX_ErrorIncorrectStateOperation;
   4384                              }
   4385                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   4386                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
   4387                                      (unsigned int)priorityMgmtype->nGroupID);
   4388 
   4389                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
   4390                                      (unsigned int)priorityMgmtype->nGroupPriority);
   4391 
   4392                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   4393                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   4394 
   4395                              break;
   4396                          }
   4397 
   4398         case OMX_IndexParamCompBufferSupplier: {
   4399                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   4400                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   4401                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
   4402                                            bufferSupplierType->eBufferSupplier);
   4403                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   4404                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   4405 
   4406                                    else
   4407 
   4408                                        eRet = OMX_ErrorBadPortIndex;
   4409 
   4410                                    break;
   4411 
   4412                                }
   4413         case OMX_IndexParamVideoAvc: {
   4414                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
   4415                                      paramIndex);
   4416                              break;
   4417                          }
   4418         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   4419                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
   4420                                      paramIndex);
   4421                              break;
   4422                         }
   4423         case OMX_IndexParamVideoH263: {
   4424                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   4425                                       paramIndex);
   4426                               break;
   4427                           }
   4428         case OMX_IndexParamVideoMpeg4: {
   4429                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   4430                                        paramIndex);
   4431                                break;
   4432                            }
   4433         case OMX_IndexParamVideoMpeg2: {
   4434                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   4435                                        paramIndex);
   4436                                break;
   4437                            }
   4438         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   4439                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
   4440                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   4441                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   4442                                      struct v4l2_control control;
   4443                                      int pic_order,rc=0;
   4444                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
   4445                                              pictureOrder->eOutputPictureOrder);
   4446                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   4447                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   4448                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   4449                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4450                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   4451                                      } else
   4452                                          eRet = OMX_ErrorBadParameter;
   4453                                      if (eRet == OMX_ErrorNone) {
   4454                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4455                                          control.value = pic_order;
   4456                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4457                                          if (rc) {
   4458                                              DEBUG_PRINT_ERROR("Set picture order failed");
   4459                                              eRet = OMX_ErrorUnsupportedSetting;
   4460                                          }
   4461                                      }
   4462                                      break;
   4463                                  }
   4464         case OMX_QcomIndexParamConcealMBMapExtraData:
   4465                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4466                                eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   4467                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4468                                break;
   4469         case OMX_QcomIndexParamFrameInfoExtraData:
   4470                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4471                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   4472                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4473                                break;
   4474         case OMX_ExtraDataFrameDimension:
   4475                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4476                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
   4477                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4478                                break;
   4479         case OMX_QcomIndexParamInterlaceExtraData:
   4480                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4481                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   4482                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4483                                break;
   4484         case OMX_QcomIndexParamH264TimeInfo:
   4485                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4486                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   4487                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4488                                break;
   4489         case OMX_QcomIndexParamVideoFramePackingExtradata:
   4490                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4491                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
   4492                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4493                                break;
   4494         case OMX_QcomIndexParamVideoQPExtraData:
   4495                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4496                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4497                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4498                                break;
   4499         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
   4500                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4501                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
   4502                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4503                                break;
   4504         case OMX_QcomIndexEnableExtnUserData:
   4505                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4506                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
   4507                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4508                                 break;
   4509         case OMX_QTIIndexParamVQZipSEIExtraData:
   4510                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4511                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4512                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4513                                 break;
   4514         case OMX_QcomIndexParamVideoDivx: {
   4515                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   4516                           }
   4517                           break;
   4518         case OMX_QcomIndexPlatformPvt: {
   4519                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN);
   4520                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
   4521                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   4522                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4523                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   4524                                    eRet = OMX_ErrorUnsupportedSetting;
   4525                                } else {
   4526                                    m_out_pvt_entry_pmem = OMX_TRUE;
   4527                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4528                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
   4529                                        m_use_output_pmem = OMX_TRUE;
   4530                                    }
   4531                                }
   4532 
   4533                            }
   4534                            break;
   4535         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   4536                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   4537                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   4538                                        struct v4l2_control control;
   4539                                        int rc;
   4540                                        drv_ctx.idr_only_decoding = 1;
   4541                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4542                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4543                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4544                                        if (rc) {
   4545                                            DEBUG_PRINT_ERROR("Set picture order failed");
   4546                                            eRet = OMX_ErrorUnsupportedSetting;
   4547                                        } else {
   4548                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   4549                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   4550                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4551                                            if (rc) {
   4552                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
   4553                                                eRet = OMX_ErrorUnsupportedSetting;
   4554                                            }
   4555                                            /*Setting sync frame decoding on driver might change buffer
   4556                                             * requirements so update them here*/
   4557                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   4558                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
   4559                                                eRet = OMX_ErrorUnsupportedSetting;
   4560                                            }
   4561                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   4562                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
   4563                                                eRet = OMX_ErrorUnsupportedSetting;
   4564                                            }
   4565                                        }
   4566                                    }
   4567                                    break;
   4568 
   4569         case OMX_QcomIndexParamIndexExtraDataType: {
   4570                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
   4571                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   4572                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   4573                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
   4574                                             (extradataIndexType->nPortIndex == 1)) {
   4575                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
   4576                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   4577 
   4578                                     }
   4579                                 }
   4580                                 break;
   4581         case OMX_QcomIndexParamEnableSmoothStreaming: {
   4582 #ifndef SMOOTH_STREAMING_DISABLED
   4583                                       eRet = enable_smoothstreaming();
   4584 #else
   4585                                       eRet = OMX_ErrorUnsupportedSetting;
   4586 #endif
   4587                                   }
   4588                                   break;
   4589 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4590                                   /* Need to allow following two set_parameters even in Idle
   4591                                    * state. This is ANDROID architecture which is not in sync
   4592                                    * with openmax standard. */
   4593         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   4594                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
   4595                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   4596                                            if (enableNativeBuffers) {
   4597                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   4598                                            }
   4599 #if !defined(FLEXYUV_SUPPORTED)
   4600                                            if (m_enable_android_native_buffers) {
   4601                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
   4602                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
   4603                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
   4604                                                    eRet = OMX_ErrorUnsupportedSetting;
   4605                                                }
   4606                                            }
   4607 #endif
   4608                                        }
   4609                                        break;
   4610         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   4611                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
   4612                                        eRet = use_android_native_buffer(hComp, paramData);
   4613                                    }
   4614                                    break;
   4615         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
   4616                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
   4617                 if (allocateNativeHandleParams != NULL) {
   4618                     allocate_native_handle = allocateNativeHandleParams->enable;
   4619                 }
   4620             }
   4621             break;
   4622 #endif
   4623         case OMX_QcomIndexParamEnableTimeStampReorder: {
   4624                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
   4625                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   4626                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   4627                                            if (reorder->bEnable == OMX_TRUE) {
   4628                                                frm_int =0;
   4629                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   4630                                            } else
   4631                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   4632                                        } else {
   4633                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   4634                                            if (reorder->bEnable == OMX_TRUE) {
   4635                                                eRet = OMX_ErrorUnsupportedSetting;
   4636                                            }
   4637                                        }
   4638                                    }
   4639                                    break;
   4640         case OMX_IndexParamVideoProfileLevelCurrent: {
   4641                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   4642                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   4643                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   4644                                      if (pParam) {
   4645                                          m_profile_lvl.eProfile = pParam->eProfile;
   4646                                          m_profile_lvl.eLevel = pParam->eLevel;
   4647                                      }
   4648                                      break;
   4649 
   4650                                  }
   4651         case OMX_QcomIndexParamVideoMetaBufferMode:
   4652         {
   4653             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
   4654             StoreMetaDataInBuffersParams *metabuffer =
   4655                 (StoreMetaDataInBuffersParams *)paramData;
   4656             if (!metabuffer) {
   4657                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   4658                 eRet = OMX_ErrorBadParameter;
   4659                 break;
   4660             }
   4661             if (m_disable_dynamic_buf_mode) {
   4662                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
   4663                 eRet = OMX_ErrorUnsupportedSetting;
   4664                 break;
   4665             }
   4666             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4667                     //set property dynamic buffer mode to driver.
   4668                     struct v4l2_control control;
   4669                     struct v4l2_format fmt;
   4670                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   4671                     if (metabuffer->bStoreMetaData == true) {
   4672                         control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   4673                     } else {
   4674                         control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
   4675                     }
   4676                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   4677                     if (!rc) {
   4678                         DEBUG_PRINT_HIGH("%s buffer mode",
   4679                            (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
   4680                                dynamic_buf_mode = metabuffer->bStoreMetaData;
   4681                     } else {
   4682                         DEBUG_PRINT_ERROR("Failed to %s buffer mode",
   4683                            (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
   4684                         eRet = OMX_ErrorUnsupportedSetting;
   4685                     }
   4686                 } else {
   4687                     DEBUG_PRINT_ERROR(
   4688                        "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
   4689                        (unsigned int)metabuffer->nPortIndex);
   4690                     eRet = OMX_ErrorUnsupportedSetting;
   4691                 }
   4692                 break;
   4693         }
   4694         case OMX_QcomIndexParamVideoDownScalar:
   4695         {
   4696             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
   4697             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
   4698             struct v4l2_control control;
   4699             int rc;
   4700             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
   4701 
   4702             if (pParam && pParam->bEnable) {
   4703                 rc = enable_downscalar();
   4704                 if (rc < 0) {
   4705                     DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   4706                     return OMX_ErrorUnsupportedSetting;
   4707                 }
   4708                 m_force_down_scalar = pParam->bEnable;
   4709             } else {
   4710                 rc = disable_downscalar();
   4711                 if (rc < 0) {
   4712                     DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   4713                     return OMX_ErrorUnsupportedSetting;
   4714                 }
   4715                 m_force_down_scalar = pParam->bEnable;
   4716             }
   4717             break;
   4718         }
   4719 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   4720         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
   4721         {
   4722             VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
   4723             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
   4724             PrepareForAdaptivePlaybackParams* pParams =
   4725                     (PrepareForAdaptivePlaybackParams *) paramData;
   4726             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4727                 if (!pParams->bEnable) {
   4728                     return OMX_ErrorNone;
   4729                 }
   4730                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
   4731                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
   4732                     DEBUG_PRINT_ERROR(
   4733                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
   4734                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
   4735                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
   4736                     eRet = OMX_ErrorBadParameter;
   4737                 } else {
   4738                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
   4739                 }
   4740             } else {
   4741                 DEBUG_PRINT_ERROR(
   4742                         "Prepare for adaptive playback supported only on output port");
   4743                 eRet = OMX_ErrorBadParameter;
   4744             }
   4745             break;
   4746         }
   4747 
   4748         case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
   4749         {
   4750             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4751             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
   4752             m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   4753             if (m_disable_dynamic_buf_mode) {
   4754                 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
   4755             }
   4756             break;
   4757         }
   4758 #endif
   4759         case OMX_QcomIndexParamVideoCustomBufferSize:
   4760         {
   4761             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
   4762             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
   4763             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
   4764             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   4765                 struct v4l2_control control;
   4766                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
   4767                 control.value = pParam->nBufferSize;
   4768                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   4769                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
   4770                     eRet = OMX_ErrorUnsupportedSetting;
   4771                 } else {
   4772                     eRet = get_buffer_req(&drv_ctx.ip_buf);
   4773                     if (eRet == OMX_ErrorNone) {
   4774                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
   4775                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
   4776                             m_custom_buffersize.input_buffersize);
   4777                     } else {
   4778                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
   4779                     }
   4780                 }
   4781             } else {
   4782                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
   4783                 eRet = OMX_ErrorBadParameter;
   4784             }
   4785             break;
   4786         }
   4787         case OMX_QTIIndexParamVQZIPSEIType:
   4788         {
   4789             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
   4790             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
   4791             OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
   4792                 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
   4793                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
   4794             eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4795                 ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4796             if (eRet != OMX_ErrorNone) {
   4797                 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
   4798                 eRet = OMX_ErrorBadParameter;
   4799                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   4800             } else {
   4801                 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4802                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4803                 if (eRet != OMX_ErrorNone) {
   4804                     DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
   4805                     eRet = OMX_ErrorBadParameter;
   4806                     client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   4807                     client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
   4808                 }
   4809             }
   4810             break;
   4811         }
   4812 
   4813         case OMX_QTIIndexParamPassInputBufferFd:
   4814         {
   4815             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4816             if (arbitrary_bytes) {
   4817                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
   4818                 eRet = OMX_ErrorUnsupportedSetting;
   4819                 break;
   4820             }
   4821 
   4822             m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   4823             if (m_input_pass_buffer_fd)
   4824                 DEBUG_PRINT_LOW("Enable passing input buffer FD");
   4825             break;
   4826         }
   4827         case OMX_QTIIndexParamForceCompressedForDPB:
   4828         {
   4829             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
   4830             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
   4831             OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
   4832                 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
   4833             if (m_disable_ubwc_mode) {
   4834                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
   4835                 eRet = OMX_ErrorUnsupportedSetting;
   4836                 break;
   4837             }
   4838             if (!paramData) {
   4839                DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
   4840                eRet = OMX_ErrorBadParameter;
   4841                break;
   4842             }
   4843 
   4844             m_force_compressed_for_dpb = pParam->bEnable;
   4845             break;
   4846         }
   4847         case OMX_QTIIndexParamForceUnCompressedForOPB:
   4848         {
   4849             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE);
   4850             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
   4851             OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
   4852                 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
   4853             if (!paramData) {
   4854                 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
   4855                 eRet = OMX_ErrorBadParameter;
   4856                 break;
   4857             }
   4858             m_disable_ubwc_mode = pParam->bEnable;
   4859             DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
   4860             break;
   4861         }
   4862 
   4863 
   4864         default: {
   4865                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
   4866                  eRet = OMX_ErrorUnsupportedIndex;
   4867              }
   4868     }
   4869     if (eRet != OMX_ErrorNone)
   4870         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
   4871     return eRet;
   4872 }
   4873 
   4874 /* ======================================================================
   4875    FUNCTION
   4876    omx_vdec::GetConfig
   4877 
   4878    DESCRIPTION
   4879    OMX Get Config Method implementation.
   4880 
   4881    PARAMETERS
   4882    <TBD>.
   4883 
   4884    RETURN VALUE
   4885    OMX Error None if successful.
   4886 
   4887    ========================================================================== */
   4888 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   4889         OMX_IN OMX_INDEXTYPE configIndex,
   4890         OMX_INOUT OMX_PTR     configData)
   4891 {
   4892     (void) hComp;
   4893     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4894 
   4895     if (m_state == OMX_StateInvalid) {
   4896         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   4897         return OMX_ErrorInvalidState;
   4898     }
   4899 
   4900     switch ((unsigned long)configIndex) {
   4901         case OMX_QcomIndexConfigInterlaced: {
   4902                                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE);
   4903                                 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   4904                                     (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   4905                                 if (configFmt->nPortIndex == 1) {
   4906                                     if (configFmt->nIndex == 0) {
   4907                                         configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   4908                                     } else if (configFmt->nIndex == 1) {
   4909                                         configFmt->eInterlaceType =
   4910                                             OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   4911                                     } else if (configFmt->nIndex == 2) {
   4912                                         configFmt->eInterlaceType =
   4913                                             OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   4914                                     } else {
   4915                                         DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   4916                                                 " NoMore Interlaced formats");
   4917                                         eRet = OMX_ErrorNoMore;
   4918                                     }
   4919 
   4920                                 } else {
   4921                                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
   4922                                             (int)configFmt->nPortIndex);
   4923                                     eRet = OMX_ErrorBadPortIndex;
   4924                                 }
   4925                                 break;
   4926                             }
   4927         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
   4928                                      VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
   4929                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   4930                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   4931                                      decoderinstances->nNumOfInstances = 16;
   4932                                      /*TODO: How to handle this case */
   4933                                      break;
   4934                                  }
   4935         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
   4936                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   4937                                               VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   4938                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
   4939                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
   4940                                               memcpy(configFmt, &m_frame_pack_arrangement,
   4941                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   4942                                           } else {
   4943                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
   4944                                           }
   4945                                           break;
   4946                                       }
   4947         case OMX_IndexConfigCommonOutputCrop: {
   4948                                   VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
   4949                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   4950                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   4951                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
   4952                                         rectangle.nLeft, rectangle.nTop,
   4953                                         rectangle.nWidth, rectangle.nHeight);
   4954                                   break;
   4955                               }
   4956         case OMX_QcomIndexConfigPerfLevel: {
   4957                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
   4958                 struct v4l2_control control;
   4959                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   4960                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   4961 
   4962                 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   4963                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   4964                     DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
   4965                     eRet = OMX_ErrorHardware;
   4966                 }
   4967 
   4968                 if (eRet == OMX_ErrorNone) {
   4969                     switch (control.value) {
   4970                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
   4971                             perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
   4972                             break;
   4973                         default:
   4974                             DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
   4975                             /* Fall through */
   4976                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
   4977                             perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
   4978                             break;
   4979                     }
   4980                 }
   4981 
   4982                 break;
   4983         }
   4984         case OMX_QcomIndexConfigH264EntropyCodingCabac: {
   4985             VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
   4986             QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
   4987             struct v4l2_control control;
   4988 
   4989             if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
   4990                 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
   4991                 eRet = OMX_ErrorNotImplemented;
   4992                 break;
   4993             }
   4994 
   4995             control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   4996             if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
   4997                 coding->bCabac = (OMX_BOOL)
   4998                     (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
   4999                 /* We can't query driver at the moment for the cabac mode, so
   5000                  * just use 0xff...f as a place holder for future improvement */
   5001                 coding->nCabacInitIdc = ~0;
   5002             } else {
   5003                 eRet = OMX_ErrorUnsupportedIndex;
   5004             }
   5005 
   5006             break;
   5007         }
   5008         case OMX_QTIIndexConfigDescribeColorAspects:
   5009         {
   5010             VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5011             DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5012 
   5013             print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
   5014             print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
   5015 
   5016             if (params->bRequestingDataSpace) {
   5017                 DEBUG_PRINT_ERROR("Does not handle dataspace request");
   5018                 return OMX_ErrorUnsupportedSetting;
   5019             }
   5020             if (m_internal_color_space.bDataSpaceChanged == OMX_TRUE) {
   5021                 DEBUG_PRINT_LOW("Updating Client's color aspects with internal");
   5022                 memcpy(&(m_client_color_space.sAspects),
   5023                         &(m_internal_color_space.sAspects), sizeof(ColorAspects));
   5024                 m_internal_color_space.bDataSpaceChanged = OMX_FALSE;
   5025             }
   5026             memcpy(&(params->sAspects), &(m_client_color_space.sAspects), sizeof(ColorAspects));
   5027 
   5028             break;
   5029         }
   5030         default: {
   5031                  DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
   5032                  eRet = OMX_ErrorBadParameter;
   5033              }
   5034 
   5035     }
   5036 
   5037     return eRet;
   5038 }
   5039 
   5040 /* ======================================================================
   5041    FUNCTION
   5042    omx_vdec::SetConfig
   5043 
   5044    DESCRIPTION
   5045    OMX Set Config method implementation
   5046 
   5047    PARAMETERS
   5048    <TBD>.
   5049 
   5050    RETURN VALUE
   5051    OMX Error None if successful.
   5052    ========================================================================== */
   5053 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   5054         OMX_IN OMX_INDEXTYPE configIndex,
   5055         OMX_IN OMX_PTR        configData)
   5056 {
   5057     (void) hComp;
   5058     if (m_state == OMX_StateInvalid) {
   5059         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   5060         return OMX_ErrorInvalidState;
   5061     }
   5062 
   5063     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5064     OMX_VIDEO_CONFIG_NALSIZE *pNal;
   5065 
   5066     DEBUG_PRINT_LOW("Set Config Called");
   5067 
   5068     if (configIndex == OMX_IndexConfigVideoNalSize) {
   5069         struct v4l2_control temp;
   5070         temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
   5071 
   5072         VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE);
   5073         pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   5074         switch (pNal->nNaluBytes) {
   5075             case 0:
   5076                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
   5077                 break;
   5078             case 2:
   5079                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
   5080                 break;
   5081             case 4:
   5082                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
   5083                 break;
   5084             default:
   5085                 return OMX_ErrorUnsupportedSetting;
   5086         }
   5087 
   5088         if (!arbitrary_bytes) {
   5089             /* In arbitrary bytes mode, the assembler strips out nal size and replaces
   5090              * with start code, so only need to notify driver in frame by frame mode */
   5091             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
   5092                 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
   5093                 return OMX_ErrorHardware;
   5094             }
   5095         }
   5096 
   5097         nal_length = pNal->nNaluBytes;
   5098         m_frame_parser.init_nal_length(nal_length);
   5099 
   5100         DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
   5101         return ret;
   5102     } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
   5103         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   5104         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
   5105 
   5106         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   5107             if (config->bEnabled) {
   5108                 if ((config->nFps >> 16) > 0) {
   5109                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
   5110                             (unsigned int)config->nFps >> 16);
   5111                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   5112                             drv_ctx.frame_rate.fps_denominator);
   5113 
   5114                     if (!drv_ctx.frame_rate.fps_numerator) {
   5115                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   5116                         drv_ctx.frame_rate.fps_numerator = 30;
   5117                     }
   5118 
   5119                     if (drv_ctx.frame_rate.fps_denominator) {
   5120                         drv_ctx.frame_rate.fps_numerator = (int)
   5121                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   5122                     }
   5123 
   5124                     drv_ctx.frame_rate.fps_denominator = 1;
   5125                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   5126                         drv_ctx.frame_rate.fps_numerator;
   5127 
   5128                     struct v4l2_outputparm oparm;
   5129                     /*XXX: we're providing timing info as seconds per frame rather than frames
   5130                      * per second.*/
   5131                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   5132                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   5133 
   5134                     struct v4l2_streamparm sparm;
   5135                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5136                     sparm.parm.output = oparm;
   5137                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   5138                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   5139                                 performance might be affected");
   5140                         ret = OMX_ErrorHardware;
   5141                     }
   5142                     client_set_fps = true;
   5143                 } else {
   5144                     DEBUG_PRINT_ERROR("Frame rate not supported.");
   5145                     ret = OMX_ErrorUnsupportedSetting;
   5146                 }
   5147             } else {
   5148                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   5149                 client_set_fps = false;
   5150             }
   5151         } else {
   5152             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   5153                     (int)config->nPortIndex);
   5154             ret = OMX_ErrorBadPortIndex;
   5155         }
   5156 
   5157         return ret;
   5158     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
   5159         OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   5160             (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   5161         struct v4l2_control control;
   5162 
   5163         DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
   5164 
   5165         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5166 
   5167         switch (perf->ePerfLevel) {
   5168             case OMX_QCOM_PerfLevelNominal:
   5169                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   5170                 break;
   5171             case OMX_QCOM_PerfLevelTurbo:
   5172                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   5173                 break;
   5174             default:
   5175                 ret = OMX_ErrorUnsupportedSetting;
   5176                 break;
   5177         }
   5178 
   5179         if (ret == OMX_ErrorNone) {
   5180             ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5181                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5182         }
   5183 
   5184         return ret;
   5185     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
   5186         OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
   5187             (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
   5188         struct v4l2_control control;
   5189         DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
   5190         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
   5191 
   5192         switch (config->eDecodeType) {
   5193             case OMX_QCOM_PictypeDecode_I:
   5194                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON;
   5195                 break;
   5196             case OMX_QCOM_PictypeDecode_IPB:
   5197             default:
   5198                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF;
   5199                 break;
   5200         }
   5201 
   5202         ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5203                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5204         if (ret)
   5205             DEBUG_PRINT_ERROR("Failed to set picture type decode");
   5206 
   5207         return ret;
   5208     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
   5209         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
   5210         DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
   5211 
   5212         struct v4l2_control control;
   5213 
   5214         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   5215         if (priority->nU32 == 0)
   5216             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
   5217         else
   5218             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   5219 
   5220         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5221             DEBUG_PRINT_ERROR("Failed to set Priority");
   5222             ret = OMX_ErrorUnsupportedSetting;
   5223         }
   5224         return ret;
   5225     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
   5226         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
   5227         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
   5228 
   5229         struct v4l2_control control;
   5230 
   5231         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
   5232         control.value = rate->nU32;
   5233 
   5234         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5235             ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
   5236                     OMX_ErrorUnsupportedSetting;
   5237             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
   5238                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
   5239         }
   5240         return ret;
   5241 
   5242     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
   5243         VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5244         DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5245         if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
   5246             enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true);
   5247         }
   5248 
   5249         print_debug_color_aspects(&(params->sAspects), "Set Config");
   5250         memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
   5251         return ret;
   5252     }
   5253 
   5254     return OMX_ErrorNotImplemented;
   5255 }
   5256 
   5257 #define extn_equals(param, extn) (!strcmp(param, extn))
   5258 
   5259 /* ======================================================================
   5260    FUNCTION
   5261    omx_vdec::GetExtensionIndex
   5262 
   5263    DESCRIPTION
   5264    OMX GetExtensionIndex method implementaion.  <TBD>
   5265 
   5266    PARAMETERS
   5267    <TBD>.
   5268 
   5269    RETURN VALUE
   5270    OMX Error None if everything successful.
   5271 
   5272    ========================================================================== */
   5273 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   5274         OMX_IN OMX_STRING      paramName,
   5275         OMX_OUT OMX_INDEXTYPE* indexType)
   5276 {
   5277     (void) hComp;
   5278     if (m_state == OMX_StateInvalid) {
   5279         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
   5280         return OMX_ErrorInvalidState;
   5281     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
   5282         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
   5283     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
   5284         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
   5285     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
   5286         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
   5287     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
   5288         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
   5289     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
   5290         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
   5291     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
   5292         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
   5293     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
   5294         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
   5295     }
   5296 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   5297     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
   5298         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   5299     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
   5300         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   5301     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
   5302         DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
   5303         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   5304     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
   5305         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   5306     } else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
   5307         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
   5308     }
   5309 #endif
   5310     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   5311         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   5312     }
   5313 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   5314     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
   5315         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
   5316     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
   5317         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
   5318     }
   5319 #endif
   5320 #ifdef FLEXYUV_SUPPORTED
   5321     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
   5322         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
   5323     }
   5324 #endif
   5325     else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
   5326         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
   5327     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
   5328         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
   5329     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
   5330         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
   5331     } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
   5332         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
   5333     } else {
   5334         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
   5335         return OMX_ErrorNotImplemented;
   5336     }
   5337     return OMX_ErrorNone;
   5338 }
   5339 
   5340 /* ======================================================================
   5341    FUNCTION
   5342    omx_vdec::GetState
   5343 
   5344    DESCRIPTION
   5345    Returns the state information back to the caller.<TBD>
   5346 
   5347    PARAMETERS
   5348    <TBD>.
   5349 
   5350    RETURN VALUE
   5351    Error None if everything is successful.
   5352    ========================================================================== */
   5353 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   5354         OMX_OUT OMX_STATETYPE* state)
   5355 {
   5356     (void) hComp;
   5357     *state = m_state;
   5358     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   5359     return OMX_ErrorNone;
   5360 }
   5361 
   5362 /* ======================================================================
   5363    FUNCTION
   5364    omx_vdec::ComponentTunnelRequest
   5365 
   5366    DESCRIPTION
   5367    OMX Component Tunnel Request method implementation. <TBD>
   5368 
   5369    PARAMETERS
   5370    None.
   5371 
   5372    RETURN VALUE
   5373    OMX Error None if everything successful.
   5374 
   5375    ========================================================================== */
   5376 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   5377         OMX_IN OMX_U32                        port,
   5378         OMX_IN OMX_HANDLETYPE        peerComponent,
   5379         OMX_IN OMX_U32                    peerPort,
   5380         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   5381 {
   5382     (void) hComp;
   5383     (void) port;
   5384     (void) peerComponent;
   5385     (void) peerPort;
   5386     (void) tunnelSetup;
   5387     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
   5388     return OMX_ErrorNotImplemented;
   5389 }
   5390 
   5391 /* ======================================================================
   5392    FUNCTION
   5393    omx_vdec::UseOutputBuffer
   5394 
   5395    DESCRIPTION
   5396    Helper function for Use buffer in the input pin
   5397 
   5398    PARAMETERS
   5399    None.
   5400 
   5401    RETURN VALUE
   5402    true/false
   5403 
   5404    ========================================================================== */
   5405 OMX_ERRORTYPE omx_vdec::allocate_extradata()
   5406 {
   5407 #ifdef USE_ION
   5408     if (drv_ctx.extradata_info.buffer_size) {
   5409         if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
   5410             munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5411             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5412             free_ion_memory(&drv_ctx.extradata_info.ion);
   5413         }
   5414         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
   5415         drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
   5416                 drv_ctx.extradata_info.size, 4096,
   5417                 &drv_ctx.extradata_info.ion.ion_alloc_data,
   5418                 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
   5419         if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
   5420             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
   5421             return OMX_ErrorInsufficientResources;
   5422         }
   5423         drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
   5424                 drv_ctx.extradata_info.size,
   5425                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5426                 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
   5427         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
   5428             DEBUG_PRINT_ERROR("Failed to map extradata memory");
   5429             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5430             free_ion_memory(&drv_ctx.extradata_info.ion);
   5431             return OMX_ErrorInsufficientResources;
   5432         }
   5433     }
   5434 #endif
   5435     if (!m_other_extradata) {
   5436         m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
   5437         if (!m_other_extradata) {
   5438             DEBUG_PRINT_ERROR("Failed to alloc memory\n");
   5439             return OMX_ErrorInsufficientResources;
   5440         }
   5441     }
   5442     return OMX_ErrorNone;
   5443 }
   5444 
   5445 void omx_vdec::free_extradata()
   5446 {
   5447 #ifdef USE_ION
   5448     if (drv_ctx.extradata_info.uaddr) {
   5449         munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5450         close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5451         free_ion_memory(&drv_ctx.extradata_info.ion);
   5452     }
   5453     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
   5454 #endif
   5455     if (m_other_extradata) {
   5456         free(m_other_extradata);
   5457         m_other_extradata = NULL;
   5458     }
   5459 }
   5460 
   5461 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
   5462         OMX_IN OMX_HANDLETYPE            hComp,
   5463         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5464         OMX_IN OMX_U32                   port,
   5465         OMX_IN OMX_PTR                   appData,
   5466         OMX_IN OMX_U32                   bytes,
   5467         OMX_IN OMX_U8*                   buffer)
   5468 {
   5469     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5470     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   5471     unsigned                         i= 0; // Temporary counter
   5472     struct vdec_setbuffer_cmd setbuffers;
   5473     OMX_PTR privateAppData = NULL;
   5474     private_handle_t *handle = NULL;
   5475     OMX_U8 *buff = buffer;
   5476     struct v4l2_buffer buf;
   5477     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5478     int extra_idx = 0;
   5479     (void) hComp;
   5480     (void) port;
   5481 
   5482     if (!m_out_mem_ptr) {
   5483         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
   5484         eRet = allocate_output_headers();
   5485         if (eRet == OMX_ErrorNone)
   5486             eRet = allocate_extradata();
   5487     }
   5488 
   5489     if (eRet == OMX_ErrorNone) {
   5490         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   5491             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   5492                 break;
   5493             }
   5494         }
   5495     }
   5496 
   5497     if (i >= drv_ctx.op_buf.actualcount) {
   5498         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
   5499         eRet = OMX_ErrorInsufficientResources;
   5500     }
   5501 
   5502     if (eRet != OMX_ErrorNone)
   5503        return eRet;
   5504 
   5505     if (dynamic_buf_mode) {
   5506         *bufferHdr = (m_out_mem_ptr + i );
   5507         (*bufferHdr)->pBuffer = NULL;
   5508         if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
   5509             enum v4l2_buf_type buf_type;
   5510             int rr = 0;
   5511             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5512             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
   5513                 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
   5514                 return OMX_ErrorInsufficientResources;
   5515             } else {
   5516                 streaming[CAPTURE_PORT] = true;
   5517                 DEBUG_PRINT_LOW("STREAMON Successful");
   5518             }
   5519 
   5520             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   5521             request_perf_level(VIDC_TURBO);
   5522         }
   5523         BITMASK_SET(&m_out_bm_count,i);
   5524         (*bufferHdr)->pAppPrivate = appData;
   5525         (*bufferHdr)->pBuffer = buffer;
   5526         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   5527         return eRet;
   5528     }
   5529 
   5530     if (eRet == OMX_ErrorNone) {
   5531 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   5532         if (m_enable_android_native_buffers) {
   5533             if (m_use_android_native_buffers) {
   5534                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   5535                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   5536                 handle = (private_handle_t *)nBuf->handle;
   5537                 privateAppData = params->pAppPrivate;
   5538             } else {
   5539                 handle = (private_handle_t *)buff;
   5540                 privateAppData = appData;
   5541             }
   5542             if (!handle) {
   5543                 DEBUG_PRINT_ERROR("handle is invalid");
   5544                 return OMX_ErrorBadParameter;
   5545             }
   5546 
   5547             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   5548                 if (secure_mode && secure_scaling_to_non_secure_opb) {
   5549                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
   5550                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   5551                 } else {
   5552                     DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   5553                             " expected %u, got %u",
   5554                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   5555                     return OMX_ErrorBadParameter;
   5556                 }
   5557             }
   5558 
   5559             drv_ctx.op_buf.buffer_size = handle->size;
   5560 
   5561             if (!m_use_android_native_buffers) {
   5562                 if (!secure_mode) {
   5563                     buff =  (OMX_U8*)mmap(0, handle->size,
   5564                             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   5565                     if (buff == MAP_FAILED) {
   5566                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   5567                         return OMX_ErrorInsufficientResources;
   5568                     }
   5569                 }
   5570             }
   5571 #if defined(_ANDROID_ICS_)
   5572             native_buffer[i].nativehandle = handle;
   5573             native_buffer[i].privatehandle = handle;
   5574 #endif
   5575             if (!handle) {
   5576                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   5577                 return OMX_ErrorBadParameter;
   5578             }
   5579             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   5580             drv_ctx.ptr_outputbuffer[i].offset = 0;
   5581             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   5582             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   5583             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   5584         } else
   5585 #endif
   5586 
   5587             if (!ouput_egl_buffers && !m_use_output_pmem) {
   5588 #ifdef USE_ION
   5589                 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   5590                         drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   5591                         &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   5592                         &drv_ctx.op_buf_ion_info[i].fd_ion_data,
   5593                         secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
   5594                 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   5595                     DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   5596                     return OMX_ErrorInsufficientResources;
   5597                 }
   5598                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5599                                       drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   5600 #else
   5601                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5602                                       open (MEM_DEVICE,O_RDWR);
   5603 
   5604                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   5605                     DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5606                     return OMX_ErrorInsufficientResources;
   5607                 }
   5608 
   5609                 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
   5610                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
   5611                     drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5612                                           open (MEM_DEVICE,O_RDWR);
   5613                     if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   5614                         DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5615                         return OMX_ErrorInsufficientResources;
   5616                     }
   5617                 }
   5618 
   5619                 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   5620                             drv_ctx.op_buf.buffer_size,
   5621                             drv_ctx.op_buf.alignment)) {
   5622                     DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   5623                     close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5624                     return OMX_ErrorInsufficientResources;
   5625                 }
   5626 #endif
   5627                 if (!secure_mode) {
   5628                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
   5629                         (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   5630                                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5631                                 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   5632                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   5633                         close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5634 #ifdef USE_ION
   5635                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   5636 #endif
   5637                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
   5638                         return OMX_ErrorInsufficientResources;
   5639                     }
   5640                 }
   5641                 drv_ctx.ptr_outputbuffer[i].offset = 0;
   5642                 privateAppData = appData;
   5643             } else {
   5644 
   5645                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   5646                 if (!appData || !bytes ) {
   5647                     if (!secure_mode && !buffer) {
   5648                         DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
   5649                         return OMX_ErrorBadParameter;
   5650                     }
   5651                 }
   5652 
   5653                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   5654                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   5655                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   5656                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
   5657                         !pmem_list->nEntries ||
   5658                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   5659                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
   5660                     return OMX_ErrorBadParameter;
   5661                 }
   5662                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   5663                     pmem_list->entryList->entry;
   5664                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   5665                         pmem_info->pmem_fd);
   5666                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   5667                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   5668                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   5669                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
   5670                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   5671                 privateAppData = appData;
   5672             }
   5673         m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   5674         m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   5675         m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   5676         m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   5677         m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   5678 
   5679         *bufferHdr = (m_out_mem_ptr + i );
   5680         if (secure_mode)
   5681             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   5682         //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   5683         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   5684                 sizeof (vdec_bufferpayload));
   5685 
   5686         DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   5687                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   5688                 drv_ctx.ptr_outputbuffer[i].pmem_fd );
   5689 
   5690         buf.index = i;
   5691         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5692         buf.memory = V4L2_MEMORY_USERPTR;
   5693         plane[0].length = drv_ctx.op_buf.buffer_size;
   5694         plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   5695             (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   5696         plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   5697         plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   5698         plane[0].data_offset = 0;
   5699         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   5700         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   5701             plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   5702             plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   5703 #ifdef USE_ION
   5704             plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   5705 #endif
   5706             plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   5707             plane[extra_idx].data_offset = 0;
   5708         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   5709             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   5710             return OMX_ErrorBadParameter;
   5711         }
   5712         buf.m.planes = plane;
   5713         buf.length = drv_ctx.num_planes;
   5714 
   5715         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
   5716             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   5717             /*TODO: How to handle this case */
   5718             return OMX_ErrorInsufficientResources;
   5719         }
   5720 
   5721         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   5722             enum v4l2_buf_type buf_type;
   5723             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5724             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   5725                 return OMX_ErrorInsufficientResources;
   5726             } else {
   5727                 streaming[CAPTURE_PORT] = true;
   5728                 DEBUG_PRINT_LOW("STREAMON Successful");
   5729             }
   5730 
   5731             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   5732             request_perf_level(VIDC_TURBO);
   5733         }
   5734 
   5735         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   5736         if (m_enable_android_native_buffers) {
   5737             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   5738             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   5739         } else {
   5740             (*bufferHdr)->pBuffer = buff;
   5741         }
   5742         (*bufferHdr)->pAppPrivate = privateAppData;
   5743         BITMASK_SET(&m_out_bm_count,i);
   5744     }
   5745     return eRet;
   5746 }
   5747 
   5748 /* ======================================================================
   5749    FUNCTION
   5750    omx_vdec::use_input_heap_buffers
   5751 
   5752    DESCRIPTION
   5753    OMX Use Buffer Heap allocation method implementation.
   5754 
   5755    PARAMETERS
   5756    <TBD>.
   5757 
   5758    RETURN VALUE
   5759    OMX Error None , if everything successful.
   5760 
   5761    ========================================================================== */
   5762 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
   5763         OMX_IN OMX_HANDLETYPE            hComp,
   5764         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5765         OMX_IN OMX_U32                   port,
   5766         OMX_IN OMX_PTR                   appData,
   5767         OMX_IN OMX_U32                   bytes,
   5768         OMX_IN OMX_U8*                   buffer)
   5769 {
   5770     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
   5771     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5772     if (!m_inp_heap_ptr)
   5773         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   5774             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   5775                     drv_ctx.ip_buf.actualcount);
   5776     if (!m_phdr_pmem_ptr)
   5777         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   5778             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   5779                     drv_ctx.ip_buf.actualcount);
   5780     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
   5781         DEBUG_PRINT_ERROR("Insufficent memory");
   5782         eRet = OMX_ErrorInsufficientResources;
   5783     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
   5784         input_use_buffer = true;
   5785         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   5786         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   5787         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   5788         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   5789         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   5790         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   5791         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   5792         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   5793         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   5794         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
   5795                     (unsigned)NULL, (unsigned)NULL)) {
   5796             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   5797             return OMX_ErrorInsufficientResources;
   5798         }
   5799         m_in_alloc_cnt++;
   5800     } else {
   5801         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
   5802         eRet = OMX_ErrorInsufficientResources;
   5803     }
   5804     return eRet;
   5805 }
   5806 
   5807 /* ======================================================================
   5808    FUNCTION
   5809    omx_vdec::UseBuffer
   5810 
   5811    DESCRIPTION
   5812    OMX Use Buffer method implementation.
   5813 
   5814    PARAMETERS
   5815    <TBD>.
   5816 
   5817    RETURN VALUE
   5818    OMX Error None , if everything successful.
   5819 
   5820    ========================================================================== */
   5821 OMX_ERRORTYPE  omx_vdec::use_buffer(
   5822         OMX_IN OMX_HANDLETYPE            hComp,
   5823         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5824         OMX_IN OMX_U32                   port,
   5825         OMX_IN OMX_PTR                   appData,
   5826         OMX_IN OMX_U32                   bytes,
   5827         OMX_IN OMX_U8*                   buffer)
   5828 {
   5829     OMX_ERRORTYPE error = OMX_ErrorNone;
   5830     struct vdec_setbuffer_cmd setbuffers;
   5831 
   5832     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
   5833             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
   5834             return OMX_ErrorBadParameter;
   5835     }
   5836     if (m_state == OMX_StateInvalid) {
   5837         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
   5838         return OMX_ErrorInvalidState;
   5839     }
   5840     if (port == OMX_CORE_INPUT_PORT_INDEX)
   5841         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   5842     else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
   5843         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
   5844     else {
   5845         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   5846         error = OMX_ErrorBadPortIndex;
   5847     }
   5848     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
   5849     if (error == OMX_ErrorNone) {
   5850         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   5851             // Send the callback now
   5852             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   5853             post_event(OMX_CommandStateSet,OMX_StateIdle,
   5854                     OMX_COMPONENT_GENERATE_EVENT);
   5855         }
   5856         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   5857                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   5858             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5859             post_event(OMX_CommandPortEnable,
   5860                     OMX_CORE_INPUT_PORT_INDEX,
   5861                     OMX_COMPONENT_GENERATE_EVENT);
   5862         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   5863                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   5864             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5865             post_event(OMX_CommandPortEnable,
   5866                     OMX_CORE_OUTPUT_PORT_INDEX,
   5867                     OMX_COMPONENT_GENERATE_EVENT);
   5868         }
   5869     }
   5870     return error;
   5871 }
   5872 
   5873 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
   5874         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
   5875 {
   5876     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
   5877         if (m_inp_heap_ptr[bufferindex].pBuffer)
   5878             free(m_inp_heap_ptr[bufferindex].pBuffer);
   5879         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
   5880     }
   5881     if (pmem_bufferHdr)
   5882         free_input_buffer(pmem_bufferHdr);
   5883     return OMX_ErrorNone;
   5884 }
   5885 
   5886 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   5887 {
   5888     unsigned int index = 0;
   5889     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   5890         return OMX_ErrorBadParameter;
   5891     }
   5892 
   5893     index = bufferHdr - m_inp_mem_ptr;
   5894     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   5895 
   5896     auto_lock l(buf_lock);
   5897     bufferHdr->pInputPortPrivate = NULL;
   5898 
   5899     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   5900         DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   5901         if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
   5902             struct vdec_setbuffer_cmd setbuffers;
   5903             setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   5904             memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   5905                     sizeof (vdec_bufferpayload));
   5906             if (!secure_mode) {
   5907                 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
   5908                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
   5909                 DEBUG_PRINT_LOW("unmap the input buffer size=%u  address = %p",
   5910                         (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size,
   5911                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
   5912                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   5913                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
   5914                 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
   5915             } else if (allocate_native_handle){
   5916                 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
   5917                 native_handle_close(nh);
   5918                 native_handle_delete(nh);
   5919             }
   5920             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   5921             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
   5922                 free(m_desc_buffer_ptr[index].buf_addr);
   5923                 m_desc_buffer_ptr[index].buf_addr = NULL;
   5924                 m_desc_buffer_ptr[index].desc_data_size = 0;
   5925             }
   5926 #ifdef USE_ION
   5927             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   5928 #endif
   5929         }
   5930     }
   5931 
   5932     return OMX_ErrorNone;
   5933 }
   5934 
   5935 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   5936 {
   5937     unsigned int index = 0;
   5938 
   5939     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   5940         return OMX_ErrorBadParameter;
   5941     }
   5942 
   5943     index = bufferHdr - m_out_mem_ptr;
   5944     DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
   5945 
   5946     if (index < drv_ctx.op_buf.actualcount
   5947             && drv_ctx.ptr_outputbuffer) {
   5948         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
   5949                 drv_ctx.ptr_outputbuffer[index].bufferaddr);
   5950 
   5951         struct vdec_setbuffer_cmd setbuffers;
   5952         setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   5953         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   5954                 sizeof (vdec_bufferpayload));
   5955 
   5956         if (!dynamic_buf_mode) {
   5957             if (streaming[CAPTURE_PORT] &&
   5958                 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
   5959                 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   5960                     DEBUG_PRINT_ERROR("STREAMOFF Failed");
   5961                 } else {
   5962                     DEBUG_PRINT_LOW("STREAMOFF Successful");
   5963                 }
   5964             }
   5965 #ifdef _ANDROID_
   5966             if (m_enable_android_native_buffers) {
   5967                 if (!secure_mode) {
   5968                     if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   5969                         munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   5970                                 drv_ctx.ptr_outputbuffer[index].mmaped_size);
   5971                     }
   5972                 }
   5973                 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   5974             } else {
   5975 #endif
   5976                 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
   5977                     if (!secure_mode) {
   5978                         DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
   5979                                 drv_ctx.ptr_outputbuffer[0].pmem_fd);
   5980                         DEBUG_PRINT_LOW("unmap the ouput buffer size=%u  address = %p",
   5981                                 (unsigned int)drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
   5982                                 drv_ctx.ptr_outputbuffer[0].bufferaddr);
   5983                         munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
   5984                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
   5985                     }
   5986                     close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
   5987                     drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
   5988 #ifdef USE_ION
   5989                     free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
   5990 #endif
   5991                 }
   5992 #ifdef _ANDROID_
   5993             }
   5994 #endif
   5995         } //!dynamic_buf_mode
   5996         if (release_output_done()) {
   5997             free_extradata();
   5998         }
   5999     }
   6000 
   6001     return OMX_ErrorNone;
   6002 
   6003 }
   6004 
   6005 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   6006         OMX_BUFFERHEADERTYPE **bufferHdr,
   6007         OMX_U32              port,
   6008         OMX_PTR              appData,
   6009         OMX_U32              bytes)
   6010 {
   6011     OMX_BUFFERHEADERTYPE *input = NULL;
   6012     unsigned char *buf_addr = NULL;
   6013     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6014     unsigned   i = 0;
   6015 
   6016     /* Sanity Check*/
   6017     if (bufferHdr == NULL) {
   6018         return OMX_ErrorBadParameter;
   6019     }
   6020 
   6021     if (m_inp_heap_ptr == NULL) {
   6022         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   6023                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   6024                          drv_ctx.ip_buf.actualcount);
   6025         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   6026                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   6027                           drv_ctx.ip_buf.actualcount);
   6028 
   6029         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
   6030             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
   6031             return OMX_ErrorInsufficientResources;
   6032         }
   6033     }
   6034 
   6035     /*Find a Free index*/
   6036     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6037         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
   6038             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6039             break;
   6040         }
   6041     }
   6042 
   6043     if (i < drv_ctx.ip_buf.actualcount) {
   6044         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   6045 
   6046         if (buf_addr == NULL) {
   6047             return OMX_ErrorInsufficientResources;
   6048         }
   6049 
   6050         *bufferHdr = (m_inp_heap_ptr + i);
   6051         input = *bufferHdr;
   6052         BITMASK_SET(&m_heap_inp_bm_count,i);
   6053 
   6054         input->pBuffer           = (OMX_U8 *)buf_addr;
   6055         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6056         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6057         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6058         input->pAppPrivate       = appData;
   6059         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6060         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
   6061         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   6062         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   6063         /*Add the Buffers to freeq*/
   6064         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
   6065                     (unsigned)NULL, (unsigned)NULL)) {
   6066             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   6067             return OMX_ErrorInsufficientResources;
   6068         }
   6069     } else {
   6070         return OMX_ErrorBadParameter;
   6071     }
   6072 
   6073     return eRet;
   6074 
   6075 }
   6076 
   6077 
   6078 /* ======================================================================
   6079    FUNCTION
   6080    omx_vdec::AllocateInputBuffer
   6081 
   6082    DESCRIPTION
   6083    Helper function for allocate buffer in the input pin
   6084 
   6085    PARAMETERS
   6086    None.
   6087 
   6088    RETURN VALUE
   6089    true/false
   6090 
   6091    ========================================================================== */
   6092 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   6093         OMX_IN OMX_HANDLETYPE            hComp,
   6094         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6095         OMX_IN OMX_U32                   port,
   6096         OMX_IN OMX_PTR                   appData,
   6097         OMX_IN OMX_U32                   bytes)
   6098 {
   6099     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6100     struct vdec_setbuffer_cmd setbuffers;
   6101     OMX_BUFFERHEADERTYPE *input = NULL;
   6102     unsigned   i = 0;
   6103     unsigned char *buf_addr = NULL;
   6104     int pmem_fd = -1;
   6105 
   6106     (void) hComp;
   6107     (void) port;
   6108 
   6109 
   6110     if (bytes != drv_ctx.ip_buf.buffer_size) {
   6111         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
   6112                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
   6113         return OMX_ErrorBadParameter;
   6114     }
   6115 
   6116     if (!m_inp_mem_ptr) {
   6117         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
   6118                 drv_ctx.ip_buf.actualcount,
   6119                 (unsigned int)drv_ctx.ip_buf.buffer_size);
   6120 
   6121         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   6122                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   6123 
   6124         if (m_inp_mem_ptr == NULL) {
   6125             return OMX_ErrorInsufficientResources;
   6126         }
   6127 
   6128         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   6129                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   6130 
   6131         if (drv_ctx.ptr_inputbuffer == NULL) {
   6132             return OMX_ErrorInsufficientResources;
   6133         }
   6134 #ifdef USE_ION
   6135         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   6136                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   6137 
   6138         if (drv_ctx.ip_buf_ion_info == NULL) {
   6139             return OMX_ErrorInsufficientResources;
   6140         }
   6141 #endif
   6142 
   6143         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   6144             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   6145 #ifdef USE_ION
   6146             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   6147 #endif
   6148         }
   6149     }
   6150 
   6151     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6152         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6153             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6154             break;
   6155         }
   6156     }
   6157 
   6158     if (i < drv_ctx.ip_buf.actualcount) {
   6159         struct v4l2_buffer buf;
   6160         struct v4l2_plane plane;
   6161         int rc;
   6162         DEBUG_PRINT_LOW("Allocate input Buffer");
   6163 #ifdef USE_ION
   6164         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   6165                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   6166                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   6167                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
   6168                 SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
   6169         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   6170             return OMX_ErrorInsufficientResources;
   6171         }
   6172         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   6173 #else
   6174         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6175 
   6176         if (pmem_fd < 0) {
   6177             DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6178             return OMX_ErrorInsufficientResources;
   6179         }
   6180 
   6181         if (pmem_fd == 0) {
   6182             pmem_fd = open (MEM_DEVICE,O_RDWR);
   6183 
   6184             if (pmem_fd < 0) {
   6185                 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6186                 return OMX_ErrorInsufficientResources;
   6187             }
   6188         }
   6189 
   6190         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   6191                     drv_ctx.ip_buf.alignment)) {
   6192             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6193             close(pmem_fd);
   6194             return OMX_ErrorInsufficientResources;
   6195         }
   6196 #endif
   6197         if (!secure_mode) {
   6198             buf_addr = (unsigned char *)mmap(NULL,
   6199                     drv_ctx.ip_buf.buffer_size,
   6200                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   6201 
   6202             if (buf_addr == MAP_FAILED) {
   6203                 close(pmem_fd);
   6204 #ifdef USE_ION
   6205                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   6206 #endif
   6207                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
   6208                 return OMX_ErrorInsufficientResources;
   6209             }
   6210         }
   6211         *bufferHdr = (m_inp_mem_ptr + i);
   6212         if (secure_mode)
   6213             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   6214         else
   6215             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   6216         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   6217         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   6218         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   6219         drv_ctx.ptr_inputbuffer [i].offset = 0;
   6220 
   6221 
   6222         buf.index = i;
   6223         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6224         buf.memory = V4L2_MEMORY_USERPTR;
   6225         plane.bytesused = 0;
   6226         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   6227         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   6228         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   6229         plane.reserved[1] = 0;
   6230         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   6231         buf.m.planes = &plane;
   6232         buf.length = 1;
   6233 
   6234         DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
   6235                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   6236 
   6237         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6238 
   6239         if (rc) {
   6240             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   6241             /*TODO: How to handle this case */
   6242             return OMX_ErrorInsufficientResources;
   6243         }
   6244 
   6245         input = *bufferHdr;
   6246         BITMASK_SET(&m_inp_bm_count,i);
   6247         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
   6248         if (allocate_native_handle) {
   6249             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
   6250             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6251             input->pBuffer = (OMX_U8 *)nh;
   6252         } else if (secure_mode || m_input_pass_buffer_fd) {
   6253             /*Legacy method, pass ion fd stashed directly in pBuffer*/
   6254             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6255         } else {
   6256             input->pBuffer           = (OMX_U8 *)buf_addr;
   6257         }
   6258         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6259         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6260         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6261         input->pAppPrivate       = appData;
   6262         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6263         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   6264 
   6265         if (drv_ctx.disable_dmx) {
   6266             eRet = allocate_desc_buffer(i);
   6267         }
   6268     } else {
   6269         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   6270         eRet = OMX_ErrorInsufficientResources;
   6271     }
   6272     return eRet;
   6273 }
   6274 
   6275 
   6276 /* ======================================================================
   6277    FUNCTION
   6278    omx_vdec::AllocateOutputBuffer
   6279 
   6280    DESCRIPTION
   6281    Helper fn for AllocateBuffer in the output pin
   6282 
   6283    PARAMETERS
   6284    <TBD>.
   6285 
   6286    RETURN VALUE
   6287    OMX Error None if everything went well.
   6288 
   6289    ========================================================================== */
   6290 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   6291         OMX_IN OMX_HANDLETYPE            hComp,
   6292         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6293         OMX_IN OMX_U32                   port,
   6294         OMX_IN OMX_PTR                   appData,
   6295         OMX_IN OMX_U32                   bytes)
   6296 {
   6297     (void)hComp;
   6298     (void)port;
   6299     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6300     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   6301     unsigned                         i= 0; // Temporary counter
   6302     struct vdec_setbuffer_cmd setbuffers;
   6303     int extra_idx = 0;
   6304 #ifdef USE_ION
   6305     int ion_device_fd =-1;
   6306     struct ion_allocation_data ion_alloc_data;
   6307     struct ion_fd_data fd_ion_data;
   6308 #endif
   6309     if (!m_out_mem_ptr) {
   6310         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
   6311                 drv_ctx.op_buf.actualcount,
   6312                 (unsigned int)drv_ctx.op_buf.buffer_size);
   6313         int nBufHdrSize        = 0;
   6314         int nPlatformEntrySize = 0;
   6315         int nPlatformListSize  = 0;
   6316         int nPMEMInfoSize = 0;
   6317         int pmem_fd = -1;
   6318         unsigned char *pmem_baseaddress = NULL;
   6319 
   6320         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   6321         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   6322         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   6323 
   6324         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
   6325                 drv_ctx.op_buf.actualcount);
   6326         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   6327             sizeof(OMX_BUFFERHEADERTYPE);
   6328 
   6329         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   6330             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   6331         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   6332             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   6333         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   6334             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   6335 
   6336         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   6337                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   6338                 nPMEMInfoSize,
   6339                 nPlatformListSize);
   6340         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
   6341                 drv_ctx.op_buf.actualcount);
   6342 #ifdef USE_ION
   6343         // Allocate output buffers as cached to improve performance of software-reading
   6344         // of the YUVs. Output buffers are cache-invalidated in driver.
   6345         // If color-conversion is involved, Only the C2D output buffers are cached, no
   6346         // need to cache the decoder's output buffers
   6347         int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
   6348         ion_device_fd = alloc_map_ion_memory(
   6349                 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
   6350                 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
   6351                 &ion_alloc_data, &fd_ion_data,
   6352                 (secure_mode && !secure_scaling_to_non_secure_opb) ?
   6353                 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
   6354         if (ion_device_fd < 0) {
   6355             return OMX_ErrorInsufficientResources;
   6356         }
   6357         pmem_fd = fd_ion_data.fd;
   6358 #else
   6359         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6360 
   6361         if (pmem_fd < 0) {
   6362             DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   6363                     drv_ctx.op_buf.buffer_size);
   6364             return OMX_ErrorInsufficientResources;
   6365         }
   6366 
   6367         if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
   6368                     drv_ctx.op_buf.actualcount,
   6369                     drv_ctx.op_buf.alignment)) {
   6370             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6371             close(pmem_fd);
   6372             return OMX_ErrorInsufficientResources;
   6373         }
   6374 #endif
   6375         if (!secure_mode) {
   6376             pmem_baseaddress = (unsigned char *)mmap(NULL,
   6377                     (drv_ctx.op_buf.buffer_size *
   6378                      drv_ctx.op_buf.actualcount),
   6379                     PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   6380             if (pmem_baseaddress == MAP_FAILED) {
   6381                 DEBUG_PRINT_ERROR("MMAP failed for Size %u",
   6382                         (unsigned int)drv_ctx.op_buf.buffer_size);
   6383                 close(pmem_fd);
   6384 #ifdef USE_ION
   6385                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   6386 #endif
   6387                 return OMX_ErrorInsufficientResources;
   6388             }
   6389         }
   6390         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   6391         // Alloc mem for platform specific info
   6392         char *pPtr=NULL;
   6393         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   6394                 nPMEMInfoSize,1);
   6395         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   6396                        calloc (sizeof(struct vdec_bufferpayload),
   6397                                drv_ctx.op_buf.actualcount);
   6398         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   6399                      calloc (sizeof (struct vdec_output_frameinfo),
   6400                              drv_ctx.op_buf.actualcount);
   6401         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   6402             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
   6403             return OMX_ErrorInsufficientResources;
   6404         }
   6405 
   6406 #ifdef USE_ION
   6407         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   6408                       calloc (sizeof(struct vdec_ion),
   6409                               drv_ctx.op_buf.actualcount);
   6410         if (!drv_ctx.op_buf_ion_info) {
   6411             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   6412             return OMX_ErrorInsufficientResources;
   6413         }
   6414 #endif
   6415 
   6416         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   6417                 && drv_ctx.ptr_respbuffer) {
   6418             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   6419                 (drv_ctx.op_buf.buffer_size *
   6420                  drv_ctx.op_buf.actualcount);
   6421             bufHdr          =  m_out_mem_ptr;
   6422             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   6423             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   6424                 (((char *) m_platform_list)  + nPlatformListSize);
   6425             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   6426                 (((char *) m_platform_entry) + nPlatformEntrySize);
   6427             pPlatformList   = m_platform_list;
   6428             pPlatformEntry  = m_platform_entry;
   6429             pPMEMInfo       = m_pmem_info;
   6430 
   6431             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   6432 
   6433             // Settting the entire storage nicely
   6434             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
   6435             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   6436             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   6437                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   6438                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   6439                 // Set the values when we determine the right HxW param
   6440                 bufHdr->nAllocLen          = bytes;
   6441                 bufHdr->nFilledLen         = 0;
   6442                 bufHdr->pAppPrivate        = appData;
   6443                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   6444                 // Platform specific PMEM Information
   6445                 // Initialize the Platform Entry
   6446                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
   6447                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   6448                 pPlatformEntry->entry      = pPMEMInfo;
   6449                 // Initialize the Platform List
   6450                 pPlatformList->nEntries    = 1;
   6451                 pPlatformList->entryList   = pPlatformEntry;
   6452                 // Keep pBuffer NULL till vdec is opened
   6453                 bufHdr->pBuffer            = NULL;
   6454                 bufHdr->nOffset            = 0;
   6455 
   6456                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   6457                 pPMEMInfo->pmem_fd = -1;
   6458                 bufHdr->pPlatformPrivate = pPlatformList;
   6459 
   6460                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   6461                 m_pmem_info[i].pmem_fd = pmem_fd;
   6462 #ifdef USE_ION
   6463                 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
   6464                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
   6465                 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
   6466 #endif
   6467 
   6468                 /*Create a mapping between buffers*/
   6469                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   6470                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   6471                                     &drv_ctx.ptr_outputbuffer[i];
   6472                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
   6473                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   6474                     pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
   6475                 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   6476                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   6477                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   6478 
   6479                 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
   6480                         pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
   6481                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   6482                 // Move the buffer and buffer header pointers
   6483                 bufHdr++;
   6484                 pPMEMInfo++;
   6485                 pPlatformEntry++;
   6486                 pPlatformList++;
   6487             }
   6488         } else {
   6489             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   6490                     m_out_mem_ptr, pPtr);
   6491             if (m_out_mem_ptr) {
   6492                 free(m_out_mem_ptr);
   6493                 m_out_mem_ptr = NULL;
   6494             }
   6495             if (pPtr) {
   6496                 free(pPtr);
   6497                 pPtr = NULL;
   6498             }
   6499             if (drv_ctx.ptr_outputbuffer) {
   6500                 free(drv_ctx.ptr_outputbuffer);
   6501                 drv_ctx.ptr_outputbuffer = NULL;
   6502             }
   6503             if (drv_ctx.ptr_respbuffer) {
   6504                 free(drv_ctx.ptr_respbuffer);
   6505                 drv_ctx.ptr_respbuffer = NULL;
   6506             }
   6507 #ifdef USE_ION
   6508             if (drv_ctx.op_buf_ion_info) {
   6509                 DEBUG_PRINT_LOW("Free o/p ion context");
   6510                 free(drv_ctx.op_buf_ion_info);
   6511                 drv_ctx.op_buf_ion_info = NULL;
   6512             }
   6513 #endif
   6514             eRet =  OMX_ErrorInsufficientResources;
   6515         }
   6516         if (eRet == OMX_ErrorNone)
   6517             eRet = allocate_extradata();
   6518     }
   6519 
   6520     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   6521         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   6522             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   6523             break;
   6524         }
   6525     }
   6526 
   6527     if (eRet == OMX_ErrorNone) {
   6528         if (i < drv_ctx.op_buf.actualcount) {
   6529             struct v4l2_buffer buf;
   6530             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   6531             int rc;
   6532             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   6533 
   6534             drv_ctx.ptr_outputbuffer[i].buffer_len =
   6535                 drv_ctx.op_buf.buffer_size;
   6536 
   6537             *bufferHdr = (m_out_mem_ptr + i );
   6538             if (secure_mode) {
   6539 #ifdef USE_ION
   6540                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   6541                     (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   6542 #else
   6543                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   6544 #endif
   6545             }
   6546             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   6547 
   6548             buf.index = i;
   6549             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6550             buf.memory = V4L2_MEMORY_USERPTR;
   6551             plane[0].length = drv_ctx.op_buf.buffer_size;
   6552             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   6553                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   6554 #ifdef USE_ION
   6555             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   6556 #endif
   6557             plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   6558             plane[0].data_offset = 0;
   6559             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   6560             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   6561                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   6562                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   6563 #ifdef USE_ION
   6564                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   6565 #endif
   6566                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   6567                 plane[extra_idx].data_offset = 0;
   6568             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   6569                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
   6570                 return OMX_ErrorBadParameter;
   6571             }
   6572             buf.m.planes = plane;
   6573             buf.length = drv_ctx.num_planes;
   6574             DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   6575             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6576             if (rc) {
   6577                 /*TODO: How to handle this case */
   6578                 return OMX_ErrorInsufficientResources;
   6579             }
   6580 
   6581             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   6582                 enum v4l2_buf_type buf_type;
   6583                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6584                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   6585                 if (rc) {
   6586                     return OMX_ErrorInsufficientResources;
   6587                 } else {
   6588                     streaming[CAPTURE_PORT] = true;
   6589                     DEBUG_PRINT_LOW("STREAMON Successful");
   6590                 }
   6591 
   6592                 DEBUG_PRINT_HIGH("Enabling Turbo mode");
   6593                 request_perf_level(VIDC_TURBO);
   6594             }
   6595 
   6596             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   6597             (*bufferHdr)->pAppPrivate = appData;
   6598             BITMASK_SET(&m_out_bm_count,i);
   6599         } else {
   6600             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
   6601             eRet = OMX_ErrorInsufficientResources;
   6602         }
   6603     }
   6604 
   6605     return eRet;
   6606 }
   6607 
   6608 
   6609 // AllocateBuffer  -- API Call
   6610 /* ======================================================================
   6611    FUNCTION
   6612    omx_vdec::AllocateBuffer
   6613 
   6614    DESCRIPTION
   6615    Returns zero if all the buffers released..
   6616 
   6617    PARAMETERS
   6618    None.
   6619 
   6620    RETURN VALUE
   6621    true/false
   6622 
   6623    ========================================================================== */
   6624 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   6625         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6626         OMX_IN OMX_U32                        port,
   6627         OMX_IN OMX_PTR                     appData,
   6628         OMX_IN OMX_U32                       bytes)
   6629 {
   6630     unsigned i = 0;
   6631     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   6632 
   6633     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
   6634     if (m_state == OMX_StateInvalid) {
   6635         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
   6636         return OMX_ErrorInvalidState;
   6637     }
   6638 
   6639     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6640         if (arbitrary_bytes) {
   6641             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   6642         } else {
   6643             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   6644         }
   6645     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6646         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   6647                 appData,bytes);
   6648     } else {
   6649         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   6650         eRet = OMX_ErrorBadPortIndex;
   6651     }
   6652     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   6653     if (eRet == OMX_ErrorNone) {
   6654         if (allocate_done()) {
   6655             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   6656                 // Send the callback now
   6657                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   6658                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   6659                         OMX_COMPONENT_GENERATE_EVENT);
   6660             }
   6661         }
   6662         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   6663             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   6664                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   6665                 post_event(OMX_CommandPortEnable,
   6666                         OMX_CORE_INPUT_PORT_INDEX,
   6667                         OMX_COMPONENT_GENERATE_EVENT);
   6668             }
   6669         }
   6670         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   6671             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   6672                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   6673                 post_event(OMX_CommandPortEnable,
   6674                         OMX_CORE_OUTPUT_PORT_INDEX,
   6675                         OMX_COMPONENT_GENERATE_EVENT);
   6676             }
   6677         }
   6678     }
   6679     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   6680     return eRet;
   6681 }
   6682 
   6683 // Free Buffer - API call
   6684 /* ======================================================================
   6685    FUNCTION
   6686    omx_vdec::FreeBuffer
   6687 
   6688    DESCRIPTION
   6689 
   6690    PARAMETERS
   6691    None.
   6692 
   6693    RETURN VALUE
   6694    true/false
   6695 
   6696    ========================================================================== */
   6697 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   6698         OMX_IN OMX_U32                 port,
   6699         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6700 {
   6701     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6702     unsigned int nPortIndex;
   6703     (void) hComp;
   6704     DEBUG_PRINT_LOW("In for decoder free_buffer");
   6705 
   6706     if (m_state == OMX_StateIdle &&
   6707             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   6708         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   6709     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   6710             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   6711         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   6712     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   6713                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   6714             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   6715              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   6716         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
   6717     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   6718         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
   6719         post_event(OMX_EventError,
   6720                 OMX_ErrorPortUnpopulated,
   6721                 OMX_COMPONENT_GENERATE_EVENT);
   6722 
   6723         return OMX_ErrorIncorrectStateOperation;
   6724     } else if (m_state != OMX_StateInvalid) {
   6725         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
   6726         post_event(OMX_EventError,
   6727                 OMX_ErrorPortUnpopulated,
   6728                 OMX_COMPONENT_GENERATE_EVENT);
   6729     }
   6730 
   6731     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6732         /*Check if arbitrary bytes*/
   6733         if (!arbitrary_bytes && !input_use_buffer)
   6734             nPortIndex = buffer - m_inp_mem_ptr;
   6735         else
   6736             nPortIndex = buffer - m_inp_heap_ptr;
   6737 
   6738         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
   6739         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
   6740                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   6741             // Clear the bit associated with it.
   6742             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   6743             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   6744             if (input_use_buffer == true) {
   6745 
   6746                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
   6747                 if (m_phdr_pmem_ptr)
   6748                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   6749             } else {
   6750                 if (arbitrary_bytes) {
   6751                     if (m_phdr_pmem_ptr)
   6752                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   6753                     else
   6754                         free_input_buffer(nPortIndex,NULL);
   6755                 } else
   6756                     free_input_buffer(buffer);
   6757             }
   6758             m_inp_bPopulated = OMX_FALSE;
   6759             if(release_input_done())
   6760                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   6761             /*Free the Buffer Header*/
   6762             if (release_input_done()) {
   6763                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
   6764                 free_input_buffer_header();
   6765             }
   6766         } else {
   6767             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
   6768             eRet = OMX_ErrorBadPortIndex;
   6769         }
   6770 
   6771         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   6772                 && release_input_done()) {
   6773             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   6774             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   6775             post_event(OMX_CommandPortDisable,
   6776                     OMX_CORE_INPUT_PORT_INDEX,
   6777                     OMX_COMPONENT_GENERATE_EVENT);
   6778         }
   6779     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6780         // check if the buffer is valid
   6781         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   6782         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   6783                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   6784             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
   6785             // Clear the bit associated with it.
   6786             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   6787             m_out_bPopulated = OMX_FALSE;
   6788             client_buffers.free_output_buffer (buffer);
   6789 
   6790             if(release_output_done()) {
   6791                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   6792             }
   6793             if (release_output_done()) {
   6794                 free_output_buffer_header();
   6795             }
   6796         } else {
   6797             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
   6798             eRet = OMX_ErrorBadPortIndex;
   6799         }
   6800         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   6801                 && release_output_done()) {
   6802             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   6803 
   6804             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   6805             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   6806 #ifdef _ANDROID_ICS_
   6807             if (m_enable_android_native_buffers) {
   6808                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   6809                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   6810             }
   6811 #endif
   6812 
   6813             post_event(OMX_CommandPortDisable,
   6814                     OMX_CORE_OUTPUT_PORT_INDEX,
   6815                     OMX_COMPONENT_GENERATE_EVENT);
   6816         }
   6817     } else {
   6818         eRet = OMX_ErrorBadPortIndex;
   6819     }
   6820     if ((eRet == OMX_ErrorNone) &&
   6821             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   6822         if (release_done()) {
   6823             // Send the callback now
   6824             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   6825             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   6826                     OMX_COMPONENT_GENERATE_EVENT);
   6827         }
   6828     }
   6829     return eRet;
   6830 }
   6831 
   6832 
   6833 /* ======================================================================
   6834    FUNCTION
   6835    omx_vdec::EmptyThisBuffer
   6836 
   6837    DESCRIPTION
   6838    This routine is used to push the encoded video frames to
   6839    the video decoder.
   6840 
   6841    PARAMETERS
   6842    None.
   6843 
   6844    RETURN VALUE
   6845    OMX Error None if everything went successful.
   6846 
   6847    ========================================================================== */
   6848 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   6849         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6850 {
   6851     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   6852     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   6853 
   6854     if (m_state != OMX_StateExecuting &&
   6855             m_state != OMX_StatePause &&
   6856             m_state != OMX_StateIdle) {
   6857         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
   6858         return OMX_ErrorInvalidState;
   6859     }
   6860 
   6861     if (buffer == NULL) {
   6862         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   6863         return OMX_ErrorBadParameter;
   6864     }
   6865 
   6866     if (!m_inp_bEnabled) {
   6867         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   6868         return OMX_ErrorIncorrectStateOperation;
   6869     }
   6870 
   6871     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   6872         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
   6873         return OMX_ErrorBadPortIndex;
   6874     }
   6875 
   6876     if (perf_flag) {
   6877         if (!latency) {
   6878             dec_time.stop();
   6879             latency = dec_time.processing_time_us();
   6880             dec_time.start();
   6881         }
   6882     }
   6883 
   6884     if (arbitrary_bytes) {
   6885         nBufferIndex = buffer - m_inp_heap_ptr;
   6886     } else {
   6887         if (input_use_buffer == true) {
   6888             nBufferIndex = buffer - m_inp_heap_ptr;
   6889             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   6890             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   6891             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   6892             buffer = &m_inp_mem_ptr[nBufferIndex];
   6893             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
   6894                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
   6895         } else {
   6896             nBufferIndex = buffer - m_inp_mem_ptr;
   6897         }
   6898     }
   6899 
   6900     if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
   6901         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   6902         return OMX_ErrorBadParameter;
   6903     }
   6904 
   6905     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   6906         codec_config_flag = true;
   6907         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   6908     }
   6909 
   6910     /* The client should not set this when codec is in arbitrary bytes mode */
   6911     if (m_input_pass_buffer_fd) {
   6912         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
   6913     }
   6914 
   6915     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
   6916             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
   6917     if (arbitrary_bytes) {
   6918         post_event ((unsigned long)hComp,(unsigned long)buffer,
   6919                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   6920     } else {
   6921         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
   6922     }
   6923     time_stamp_dts.insert_timestamp(buffer);
   6924     return OMX_ErrorNone;
   6925 }
   6926 
   6927 /* ======================================================================
   6928    FUNCTION
   6929    omx_vdec::empty_this_buffer_proxy
   6930 
   6931    DESCRIPTION
   6932    This routine is used to push the encoded video frames to
   6933    the video decoder.
   6934 
   6935    PARAMETERS
   6936    None.
   6937 
   6938    RETURN VALUE
   6939    OMX Error None if everything went successful.
   6940 
   6941    ========================================================================== */
   6942 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   6943         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6944 {
   6945     (void) hComp;
   6946     int push_cnt = 0,i=0;
   6947     unsigned nPortIndex = 0;
   6948     OMX_ERRORTYPE ret = OMX_ErrorNone;
   6949     struct vdec_input_frameinfo frameinfo;
   6950     struct vdec_bufferpayload *temp_buffer;
   6951     struct vdec_seqheader seq_header;
   6952     bool port_setting_changed = true;
   6953 
   6954     /*Should we generate a Aync error event*/
   6955     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   6956         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   6957         return OMX_ErrorBadParameter;
   6958     }
   6959 
   6960     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   6961 
   6962     if (nPortIndex > drv_ctx.ip_buf.actualcount) {
   6963         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   6964                 nPortIndex);
   6965         return OMX_ErrorBadParameter;
   6966     }
   6967 
   6968     pending_input_buffers++;
   6969 
   6970     /* return zero length and not an EOS buffer */
   6971     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   6972             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   6973         DEBUG_PRINT_HIGH("return zero legth buffer");
   6974         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   6975                 OMX_COMPONENT_GENERATE_EBD);
   6976         return OMX_ErrorNone;
   6977     }
   6978 
   6979     if (input_flush_progress == true) {
   6980         DEBUG_PRINT_LOW("Flush in progress return buffer ");
   6981         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   6982                 OMX_COMPONENT_GENERATE_EBD);
   6983         return OMX_ErrorNone;
   6984     }
   6985 
   6986     auto_lock l(buf_lock);
   6987     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   6988 
   6989     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
   6990         return OMX_ErrorBadParameter;
   6991     }
   6992     /* If its first frame, H264 codec and reject is true, then parse the nal
   6993        and get the profile. Based on this, reject the clip playback */
   6994     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   6995             m_reject_avc_1080p_mp) {
   6996         first_frame = 1;
   6997         DEBUG_PRINT_ERROR("Parse nal to get the profile");
   6998         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   6999                 NALU_TYPE_SPS);
   7000         m_profile = h264_parser->get_profile();
   7001         ret = is_video_session_supported();
   7002         if (ret) {
   7003             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   7004             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   7005             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   7006             m_state = OMX_StateInvalid;
   7007             return OMX_ErrorNone;
   7008         }
   7009     }
   7010 
   7011     DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7012     /*for use buffer we need to memcpy the data*/
   7013     temp_buffer->buffer_len = buffer->nFilledLen;
   7014 
   7015     if (input_use_buffer && temp_buffer->bufferaddr) {
   7016         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   7017             if (arbitrary_bytes) {
   7018                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   7019             } else {
   7020                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   7021                         buffer->nFilledLen);
   7022             }
   7023         } else {
   7024             return OMX_ErrorBadParameter;
   7025         }
   7026 
   7027     }
   7028 
   7029     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   7030     frameinfo.client_data = (void *) buffer;
   7031     frameinfo.datalen = temp_buffer->buffer_len;
   7032     frameinfo.flags = 0;
   7033     frameinfo.offset = buffer->nOffset;
   7034     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   7035     frameinfo.pmem_offset = temp_buffer->offset;
   7036     frameinfo.timestamp = buffer->nTimeStamp;
   7037     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   7038         DEBUG_PRINT_LOW("ETB: dmx enabled");
   7039         if (m_demux_entries == 0) {
   7040             extract_demux_addr_offsets(buffer);
   7041         }
   7042 
   7043         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
   7044         handle_demux_data(buffer);
   7045         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   7046         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   7047     } else {
   7048         frameinfo.desc_addr = NULL;
   7049         frameinfo.desc_size = 0;
   7050     }
   7051     if (!arbitrary_bytes) {
   7052         frameinfo.flags |= buffer->nFlags;
   7053     }
   7054 
   7055 #ifdef _ANDROID_
   7056     if (m_debug_timestamp) {
   7057         if (arbitrary_bytes) {
   7058             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7059             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7060         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7061             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7062             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7063         }
   7064     }
   7065 #endif
   7066 
   7067     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
   7068 
   7069 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7070         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7071         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7072     }
   7073 
   7074     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7075         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
   7076         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   7077         h264_scratch.nFilledLen = 0;
   7078         nal_count = 0;
   7079         look_ahead_nal = false;
   7080         frame_count = 0;
   7081         if (m_frame_parser.mutils)
   7082             m_frame_parser.mutils->initialize_frame_checking_environment();
   7083         m_frame_parser.flush();
   7084         h264_last_au_ts = LLONG_MAX;
   7085         h264_last_au_flags = 0;
   7086         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   7087         m_demux_entries = 0;
   7088     }
   7089     struct v4l2_buffer buf;
   7090     struct v4l2_plane plane;
   7091     memset( (void *)&buf, 0, sizeof(buf));
   7092     memset( (void *)&plane, 0, sizeof(plane));
   7093     int rc;
   7094     unsigned long  print_count;
   7095     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7096         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   7097         DEBUG_PRINT_HIGH("INPUT EOS reached") ;
   7098     }
   7099     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7100     buf.index = nPortIndex;
   7101     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7102     buf.memory = V4L2_MEMORY_USERPTR;
   7103     plane.bytesused = temp_buffer->buffer_len;
   7104     plane.length = drv_ctx.ip_buf.buffer_size;
   7105     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   7106         (unsigned long)temp_buffer->offset;
   7107     plane.reserved[0] = temp_buffer->pmem_fd;
   7108     plane.reserved[1] = temp_buffer->offset;
   7109     plane.data_offset = 0;
   7110     buf.m.planes = &plane;
   7111     buf.length = 1;
   7112     if (frameinfo.timestamp >= LLONG_MAX) {
   7113         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   7114     }
   7115     //assumption is that timestamp is in milliseconds
   7116     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   7117     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   7118     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   7119     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   7120 
   7121     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7122         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
   7123         android_atomic_inc(&m_queued_codec_config_count);
   7124     }
   7125 
   7126     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7127     if (rc) {
   7128         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
   7129         return OMX_ErrorHardware;
   7130     }
   7131 
   7132     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7133         codec_config_flag = false;
   7134     }
   7135     if (!streaming[OUTPUT_PORT]) {
   7136         enum v4l2_buf_type buf_type;
   7137         int ret,r;
   7138 
   7139         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7140         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   7141         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7142         if (!ret) {
   7143             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
   7144             streaming[OUTPUT_PORT] = true;
   7145         } else if (errno == EBUSY) {
   7146             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
   7147             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7148                     OMX_COMPONENT_GENERATE_EBD);
   7149             return OMX_ErrorInsufficientResources;
   7150         } else {
   7151             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
   7152             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   7153             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7154                     OMX_COMPONENT_GENERATE_EBD);
   7155             return OMX_ErrorBadParameter;
   7156         }
   7157     }
   7158     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
   7159             frameinfo.bufferaddr, (long long)frameinfo.timestamp,
   7160             (unsigned int)frameinfo.datalen);
   7161 
   7162     return ret;
   7163 }
   7164 
   7165 /* ======================================================================
   7166    FUNCTION
   7167    omx_vdec::FillThisBuffer
   7168 
   7169    DESCRIPTION
   7170    IL client uses this method to release the frame buffer
   7171    after displaying them.
   7172 
   7173    PARAMETERS
   7174    None.
   7175 
   7176    RETURN VALUE
   7177    true/false
   7178 
   7179    ========================================================================== */
   7180 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   7181         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7182 {
   7183     if (m_state != OMX_StateExecuting &&
   7184             m_state != OMX_StatePause &&
   7185             m_state != OMX_StateIdle) {
   7186         DEBUG_PRINT_ERROR("FTB in Invalid State");
   7187         return OMX_ErrorInvalidState;
   7188     }
   7189 
   7190     if (!m_out_bEnabled) {
   7191         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   7192         return OMX_ErrorIncorrectStateOperation;
   7193     }
   7194 
   7195     unsigned nPortIndex = 0;
   7196     if (dynamic_buf_mode) {
   7197         private_handle_t *handle = NULL;
   7198         struct VideoDecoderOutputMetaData *meta;
   7199         unsigned int nPortIndex = 0;
   7200 
   7201         if (!buffer || !buffer->pBuffer) {
   7202             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
   7203             return OMX_ErrorBadParameter;
   7204         }
   7205 
   7206         //get the buffer type and fd info
   7207         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   7208         handle = (private_handle_t *)meta->pHandle;
   7209         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
   7210 
   7211         if (!handle) {
   7212             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
   7213             return OMX_ErrorBadParameter;
   7214         }
   7215         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   7216         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7217         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7218             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   7219             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   7220             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   7221 
   7222            //Store private handle from GraphicBuffer
   7223             native_buffer[nPortIndex].privatehandle = handle;
   7224             native_buffer[nPortIndex].nativehandle = handle;
   7225         } else {
   7226             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
   7227             return OMX_ErrorBadParameter;
   7228         }
   7229 
   7230         //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
   7231         //this with a more sane size so that we don't compensate in rest of code
   7232         //We'll restore this size later on, so that it's transparent to client
   7233         buffer->nFilledLen = 0;
   7234         buffer->nAllocLen = handle->size;
   7235         drv_ctx.op_buf.buffer_size = handle->size;
   7236     }
   7237 
   7238     nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7239     if (buffer == NULL ||
   7240             (nPortIndex >= drv_ctx.op_buf.actualcount)) {
   7241         DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7242             nPortIndex, drv_ctx.op_buf.actualcount);
   7243         return OMX_ErrorBadParameter;
   7244     }
   7245 
   7246     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   7247         DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
   7248         return OMX_ErrorBadPortIndex;
   7249     }
   7250 
   7251     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7252     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
   7253     return OMX_ErrorNone;
   7254 }
   7255 /* ======================================================================
   7256    FUNCTION
   7257    omx_vdec::fill_this_buffer_proxy
   7258 
   7259    DESCRIPTION
   7260    IL client uses this method to release the frame buffer
   7261    after displaying them.
   7262 
   7263    PARAMETERS
   7264    None.
   7265 
   7266    RETURN VALUE
   7267    true/false
   7268 
   7269    ========================================================================== */
   7270 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   7271         OMX_IN OMX_HANDLETYPE        hComp,
   7272         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   7273 {
   7274     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   7275     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   7276     unsigned nPortIndex = 0;
   7277     struct vdec_fillbuffer_cmd fillbuffer;
   7278     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   7279     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   7280 
   7281     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7282 
   7283     if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
   7284         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7285             nPortIndex, drv_ctx.op_buf.actualcount);
   7286         return OMX_ErrorBadParameter;
   7287     }
   7288 
   7289     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   7290             bufferAdd, bufferAdd->pBuffer);
   7291     /*Return back the output buffer to client*/
   7292     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
   7293         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
   7294         buffer->nFilledLen = 0;
   7295         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   7296         return OMX_ErrorNone;
   7297     }
   7298 
   7299     if (dynamic_buf_mode) {
   7300         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   7301         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen;
   7302         buf_ref_add(nPortIndex);
   7303         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen;
   7304     }
   7305 
   7306     pending_output_buffers++;
   7307     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   7308     if (!buffer) {
   7309        DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
   7310        return OMX_ErrorBadParameter;
   7311     }
   7312     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   7313     if (ptr_respbuffer) {
   7314         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   7315     }
   7316 
   7317     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   7318         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   7319         buffer->nFilledLen = 0;
   7320         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   7321         pending_output_buffers--;
   7322         return OMX_ErrorBadParameter;
   7323     }
   7324 
   7325     int rc = 0;
   7326     struct v4l2_buffer buf;
   7327     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   7328     memset( (void *)&buf, 0, sizeof(buf));
   7329     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   7330     unsigned int extra_idx = 0;
   7331 
   7332     buf.index = nPortIndex;
   7333     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7334     buf.memory = V4L2_MEMORY_USERPTR;
   7335     plane[0].bytesused = buffer->nFilledLen;
   7336     plane[0].length = buffer->nAllocLen;
   7337     plane[0].m.userptr =
   7338         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   7339         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   7340     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   7341     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   7342     plane[0].data_offset = 0;
   7343     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   7344     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   7345         plane[extra_idx].bytesused = 0;
   7346         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   7347         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   7348 #ifdef USE_ION
   7349         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   7350 #endif
   7351         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   7352         plane[extra_idx].data_offset = 0;
   7353     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   7354         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   7355         return OMX_ErrorBadParameter;
   7356     }
   7357     buf.m.planes = plane;
   7358     buf.length = drv_ctx.num_planes;
   7359     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   7360              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress);
   7361 
   7362     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7363     if (rc) {
   7364         /*TODO: How to handle this case */
   7365         DEBUG_PRINT_ERROR("Failed to qbuf to driver");
   7366     }
   7367 return OMX_ErrorNone;
   7368 }
   7369 
   7370 /* ======================================================================
   7371    FUNCTION
   7372    omx_vdec::SetCallbacks
   7373 
   7374    DESCRIPTION
   7375    Set the callbacks.
   7376 
   7377    PARAMETERS
   7378    None.
   7379 
   7380    RETURN VALUE
   7381    OMX Error None if everything successful.
   7382 
   7383    ========================================================================== */
   7384 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   7385         OMX_IN OMX_CALLBACKTYPE* callbacks,
   7386         OMX_IN OMX_PTR             appData)
   7387 {
   7388     (void) hComp;
   7389     m_cb       = *callbacks;
   7390     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   7391             m_cb.EventHandler,m_cb.FillBufferDone);
   7392     m_app_data =    appData;
   7393     return OMX_ErrorNotImplemented;
   7394 }
   7395 
   7396 /* ======================================================================
   7397    FUNCTION
   7398    omx_vdec::ComponentDeInit
   7399 
   7400    DESCRIPTION
   7401    Destroys the component and release memory allocated to the heap.
   7402 
   7403    PARAMETERS
   7404    <TBD>.
   7405 
   7406    RETURN VALUE
   7407    OMX Error None if everything successful.
   7408 
   7409    ========================================================================== */
   7410 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   7411 {
   7412    (void) hComp;
   7413 
   7414     unsigned i = 0;
   7415     if (OMX_StateLoaded != m_state) {
   7416         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
   7417                 m_state);
   7418         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   7419     } else {
   7420         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
   7421     }
   7422 
   7423     /*Check if the output buffers have to be cleaned up*/
   7424     if (m_out_mem_ptr) {
   7425         DEBUG_PRINT_LOW("Freeing the Output Memory");
   7426         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   7427             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
   7428                 BITMASK_CLEAR(&m_out_bm_count, i);
   7429                 client_buffers.free_output_buffer (&m_out_mem_ptr[i]);
   7430             }
   7431 
   7432             if (release_output_done()) {
   7433                 break;
   7434             }
   7435         }
   7436 #ifdef _ANDROID_ICS_
   7437         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   7438 #endif
   7439     }
   7440 
   7441     /*Check if the input buffers have to be cleaned up*/
   7442     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   7443         DEBUG_PRINT_LOW("Freeing the Input Memory");
   7444         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   7445 
   7446             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
   7447                 BITMASK_CLEAR(&m_inp_bm_count, i);
   7448                 if (m_inp_mem_ptr)
   7449                     free_input_buffer (i,&m_inp_mem_ptr[i]);
   7450                 else
   7451                     free_input_buffer (i,NULL);
   7452             }
   7453 
   7454             if (release_input_done()) {
   7455                 break;
   7456             }
   7457        }
   7458     }
   7459     free_input_buffer_header();
   7460     free_output_buffer_header();
   7461     if (h264_scratch.pBuffer) {
   7462         free(h264_scratch.pBuffer);
   7463         h264_scratch.pBuffer = NULL;
   7464     }
   7465 
   7466     if (h264_parser) {
   7467         delete h264_parser;
   7468         h264_parser = NULL;
   7469     }
   7470 
   7471     if (m_frame_parser.mutils) {
   7472         DEBUG_PRINT_LOW("Free utils parser");
   7473         delete (m_frame_parser.mutils);
   7474         m_frame_parser.mutils = NULL;
   7475     }
   7476 
   7477     if (m_platform_list) {
   7478         free(m_platform_list);
   7479         m_platform_list = NULL;
   7480     }
   7481     if (m_vendor_config.pData) {
   7482         free(m_vendor_config.pData);
   7483         m_vendor_config.pData = NULL;
   7484     }
   7485 
   7486     // Reset counters in mesg queues
   7487     m_ftb_q.m_size=0;
   7488     m_cmd_q.m_size=0;
   7489     m_etb_q.m_size=0;
   7490     m_ftb_q.m_read = m_ftb_q.m_write =0;
   7491     m_cmd_q.m_read = m_cmd_q.m_write =0;
   7492     m_etb_q.m_read = m_etb_q.m_write =0;
   7493 #ifdef _ANDROID_
   7494     if (m_debug_timestamp) {
   7495         m_timestamp_list.reset_ts_list();
   7496     }
   7497 #endif
   7498 
   7499     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
   7500     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   7501     // NULL);
   7502     DEBUG_PRINT_HIGH("Close the driver instance");
   7503 
   7504     if (m_debug.infile) {
   7505         fclose(m_debug.infile);
   7506         m_debug.infile = NULL;
   7507     }
   7508     if (m_debug.outfile) {
   7509         fclose(m_debug.outfile);
   7510         m_debug.outfile = NULL;
   7511     }
   7512     if (m_debug.out_ymeta_file) {
   7513         fclose(m_debug.out_ymeta_file);
   7514         m_debug.out_ymeta_file = NULL;
   7515     }
   7516     if (m_debug.out_uvmeta_file) {
   7517         fclose(m_debug.out_uvmeta_file);
   7518         m_debug.out_uvmeta_file = NULL;
   7519     }
   7520 #ifdef OUTPUT_EXTRADATA_LOG
   7521     if (outputExtradataFile)
   7522         fclose (outputExtradataFile);
   7523 #endif
   7524     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
   7525     return OMX_ErrorNone;
   7526 }
   7527 
   7528 /* ======================================================================
   7529    FUNCTION
   7530    omx_vdec::UseEGLImage
   7531 
   7532    DESCRIPTION
   7533    OMX Use EGL Image method implementation <TBD>.
   7534 
   7535    PARAMETERS
   7536    <TBD>.
   7537 
   7538    RETURN VALUE
   7539    Not Implemented error.
   7540 
   7541    ========================================================================== */
   7542 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
   7543         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   7544         OMX_IN OMX_U32                        port,
   7545         OMX_IN OMX_PTR                     appData,
   7546         OMX_IN void*                      eglImage)
   7547 {
   7548     (void) appData;
   7549     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   7550     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   7551     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   7552 
   7553 #ifdef USE_EGL_IMAGE_GPU
   7554     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   7555     EGLint fd = -1, offset = 0,pmemPtr = 0;
   7556 #else
   7557     int fd = -1, offset = 0;
   7558 #endif
   7559     DEBUG_PRINT_HIGH("use EGL image support for decoder");
   7560     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   7561         DEBUG_PRINT_ERROR("Invalid EGL image");
   7562     }
   7563 #ifdef USE_EGL_IMAGE_GPU
   7564     if (m_display_id == NULL) {
   7565         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
   7566         return OMX_ErrorInsufficientResources;
   7567     }
   7568     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   7569         eglGetProcAddress("eglQueryImageKHR");
   7570     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
   7571     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
   7572     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
   7573 #else //with OMX test app
   7574     struct temp_egl {
   7575         int pmem_fd;
   7576         int offset;
   7577     };
   7578     struct temp_egl *temp_egl_id = NULL;
   7579     void * pmemPtr = (void *) eglImage;
   7580     temp_egl_id = (struct temp_egl *)eglImage;
   7581     if (temp_egl_id != NULL) {
   7582         fd = temp_egl_id->pmem_fd;
   7583         offset = temp_egl_id->offset;
   7584     }
   7585 #endif
   7586     if (fd < 0) {
   7587         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
   7588         return OMX_ErrorInsufficientResources;
   7589     }
   7590     pmem_info.pmem_fd = (OMX_U32) fd;
   7591     pmem_info.offset = (OMX_U32) offset;
   7592     pmem_entry.entry = (void *) &pmem_info;
   7593     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   7594     pmem_list.entryList = &pmem_entry;
   7595     pmem_list.nEntries = 1;
   7596     ouput_egl_buffers = true;
   7597     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   7598                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   7599                 (OMX_U8 *)pmemPtr)) {
   7600         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
   7601         return OMX_ErrorInsufficientResources;
   7602     }
   7603     return OMX_ErrorNone;
   7604 }
   7605 
   7606 /* ======================================================================
   7607    FUNCTION
   7608    omx_vdec::ComponentRoleEnum
   7609 
   7610    DESCRIPTION
   7611    OMX Component Role Enum method implementation.
   7612 
   7613    PARAMETERS
   7614    <TBD>.
   7615 
   7616    RETURN VALUE
   7617    OMX Error None if everything is successful.
   7618    ========================================================================== */
   7619 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   7620         OMX_OUT OMX_U8*        role,
   7621         OMX_IN OMX_U32        index)
   7622 {
   7623     (void) hComp;
   7624     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7625 
   7626     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   7627         if ((0 == index) && role) {
   7628             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   7629             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7630         } else {
   7631             eRet = OMX_ErrorNoMore;
   7632         }
   7633     }
   7634     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   7635         if ((0 == index) && role) {
   7636             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   7637             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7638         } else {
   7639             eRet = OMX_ErrorNoMore;
   7640         }
   7641     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   7642         if ((0 == index) && role) {
   7643             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   7644             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7645         } else {
   7646             DEBUG_PRINT_LOW("No more roles");
   7647             eRet = OMX_ErrorNoMore;
   7648         }
   7649     }
   7650 
   7651     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   7652             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) {
   7653         if ((0 == index) && role) {
   7654             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   7655             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7656         } else {
   7657             DEBUG_PRINT_LOW("No more roles");
   7658             eRet = OMX_ErrorNoMore;
   7659         }
   7660     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   7661         if ((0 == index) && role) {
   7662             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   7663             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7664         } else {
   7665             DEBUG_PRINT_LOW("No more roles");
   7666             eRet = OMX_ErrorNoMore;
   7667         }
   7668     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   7669         if ((0 == index) && role) {
   7670             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   7671             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7672         } else {
   7673             DEBUG_PRINT_LOW("No more roles");
   7674             eRet = OMX_ErrorNoMore;
   7675         }
   7676     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   7677         if ((0 == index) && role) {
   7678             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   7679             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   7680         } else {
   7681             DEBUG_PRINT_LOW("No more roles");
   7682             eRet = OMX_ErrorNoMore;
   7683         }
   7684     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   7685             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   7686           ) {
   7687         if ((0 == index) && role) {
   7688             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   7689             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7690         } else {
   7691             DEBUG_PRINT_LOW("No more roles");
   7692             eRet = OMX_ErrorNoMore;
   7693         }
   7694     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   7695         if ((0 == index) && role) {
   7696             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   7697             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7698         } else {
   7699             DEBUG_PRINT_LOW("No more roles");
   7700             eRet = OMX_ErrorNoMore;
   7701         }
   7702     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   7703         if ((0 == index) && role) {
   7704             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   7705             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7706         } else {
   7707             DEBUG_PRINT_LOW("No more roles");
   7708             eRet = OMX_ErrorNoMore;
   7709         }
   7710     } else {
   7711         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
   7712         eRet = OMX_ErrorInvalidComponentName;
   7713     }
   7714     return eRet;
   7715 }
   7716 
   7717 
   7718 
   7719 
   7720 /* ======================================================================
   7721    FUNCTION
   7722    omx_vdec::AllocateDone
   7723 
   7724    DESCRIPTION
   7725    Checks if entire buffer pool is allocated by IL Client or not.
   7726    Need this to move to IDLE state.
   7727 
   7728    PARAMETERS
   7729    None.
   7730 
   7731    RETURN VALUE
   7732    true/false.
   7733 
   7734    ========================================================================== */
   7735 bool omx_vdec::allocate_done(void)
   7736 {
   7737     bool bRet = false;
   7738     bool bRet_In = false;
   7739     bool bRet_Out = false;
   7740 
   7741     bRet_In = allocate_input_done();
   7742     bRet_Out = allocate_output_done();
   7743 
   7744     if (bRet_In && bRet_Out) {
   7745         bRet = true;
   7746     }
   7747 
   7748     return bRet;
   7749 }
   7750 /* ======================================================================
   7751    FUNCTION
   7752    omx_vdec::AllocateInputDone
   7753 
   7754    DESCRIPTION
   7755    Checks if I/P buffer pool is allocated by IL Client or not.
   7756 
   7757    PARAMETERS
   7758    None.
   7759 
   7760    RETURN VALUE
   7761    true/false.
   7762 
   7763    ========================================================================== */
   7764 bool omx_vdec::allocate_input_done(void)
   7765 {
   7766     bool bRet = false;
   7767     unsigned i=0;
   7768 
   7769     if (m_inp_mem_ptr == NULL) {
   7770         return bRet;
   7771     }
   7772     if (m_inp_mem_ptr ) {
   7773         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   7774             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   7775                 break;
   7776             }
   7777         }
   7778     }
   7779     if (i == drv_ctx.ip_buf.actualcount) {
   7780         bRet = true;
   7781         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   7782     }
   7783     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   7784         m_inp_bPopulated = OMX_TRUE;
   7785     }
   7786     return bRet;
   7787 }
   7788 /* ======================================================================
   7789    FUNCTION
   7790    omx_vdec::AllocateOutputDone
   7791 
   7792    DESCRIPTION
   7793    Checks if entire O/P buffer pool is allocated by IL Client or not.
   7794 
   7795    PARAMETERS
   7796    None.
   7797 
   7798    RETURN VALUE
   7799    true/false.
   7800 
   7801    ========================================================================== */
   7802 bool omx_vdec::allocate_output_done(void)
   7803 {
   7804     bool bRet = false;
   7805     unsigned j=0;
   7806 
   7807     if (m_out_mem_ptr == NULL) {
   7808         return bRet;
   7809     }
   7810 
   7811     if (m_out_mem_ptr) {
   7812         for (; j < drv_ctx.op_buf.actualcount; j++) {
   7813             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   7814                 break;
   7815             }
   7816         }
   7817     }
   7818 
   7819     if (j == drv_ctx.op_buf.actualcount) {
   7820         bRet = true;
   7821         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   7822         if (m_out_bEnabled)
   7823             m_out_bPopulated = OMX_TRUE;
   7824     }
   7825 
   7826     return bRet;
   7827 }
   7828 
   7829 /* ======================================================================
   7830    FUNCTION
   7831    omx_vdec::ReleaseDone
   7832 
   7833    DESCRIPTION
   7834    Checks if IL client has released all the buffers.
   7835 
   7836    PARAMETERS
   7837    None.
   7838 
   7839    RETURN VALUE
   7840    true/false
   7841 
   7842    ========================================================================== */
   7843 bool omx_vdec::release_done(void)
   7844 {
   7845     bool bRet = false;
   7846 
   7847     if (release_input_done()) {
   7848         if (release_output_done()) {
   7849             bRet = true;
   7850         }
   7851     }
   7852     return bRet;
   7853 }
   7854 
   7855 
   7856 /* ======================================================================
   7857    FUNCTION
   7858    omx_vdec::ReleaseOutputDone
   7859 
   7860    DESCRIPTION
   7861    Checks if IL client has released all the buffers.
   7862 
   7863    PARAMETERS
   7864    None.
   7865 
   7866    RETURN VALUE
   7867    true/false
   7868 
   7869    ========================================================================== */
   7870 bool omx_vdec::release_output_done(void)
   7871 {
   7872     bool bRet = false;
   7873     unsigned i=0,j=0;
   7874 
   7875     DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr);
   7876     if (m_out_mem_ptr) {
   7877         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   7878             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   7879                 break;
   7880             }
   7881         }
   7882         if (j == drv_ctx.op_buf.actualcount) {
   7883             m_out_bm_count = 0;
   7884             bRet = true;
   7885         }
   7886     } else {
   7887         m_out_bm_count = 0;
   7888         bRet = true;
   7889     }
   7890     return bRet;
   7891 }
   7892 /* ======================================================================
   7893    FUNCTION
   7894    omx_vdec::ReleaseInputDone
   7895 
   7896    DESCRIPTION
   7897    Checks if IL client has released all the buffers.
   7898 
   7899    PARAMETERS
   7900    None.
   7901 
   7902    RETURN VALUE
   7903    true/false
   7904 
   7905    ========================================================================== */
   7906 bool omx_vdec::release_input_done(void)
   7907 {
   7908     bool bRet = false;
   7909     unsigned i=0,j=0;
   7910 
   7911     DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   7912     if (m_inp_mem_ptr) {
   7913         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   7914             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   7915                 break;
   7916             }
   7917         }
   7918         if (j==drv_ctx.ip_buf.actualcount) {
   7919             bRet = true;
   7920         }
   7921     } else {
   7922         bRet = true;
   7923     }
   7924     return bRet;
   7925 }
   7926 
   7927 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   7928         OMX_BUFFERHEADERTYPE * buffer)
   7929 {
   7930     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   7931     if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
   7932         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
   7933         return OMX_ErrorBadParameter;
   7934     } else if (output_flush_progress) {
   7935         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   7936         buffer->nFilledLen = 0;
   7937         buffer->nTimeStamp = 0;
   7938         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   7939         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7940         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   7941     }
   7942 
   7943     if (m_debug_extradata) {
   7944         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7945             DEBUG_PRINT_HIGH("***************************************************");
   7946             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   7947             DEBUG_PRINT_HIGH("***************************************************");
   7948         }
   7949 
   7950         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   7951             DEBUG_PRINT_HIGH("***************************************************");
   7952             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   7953             DEBUG_PRINT_HIGH("***************************************************");
   7954         }
   7955     }
   7956 
   7957 
   7958     DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld",
   7959             buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp);
   7960     pending_output_buffers --;
   7961 
   7962     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   7963         DEBUG_PRINT_HIGH("Output EOS has been reached");
   7964         if (!output_flush_progress)
   7965             post_event((unsigned)NULL, (unsigned)NULL,
   7966                     OMX_COMPONENT_GENERATE_EOS_DONE);
   7967 
   7968         if (psource_frame) {
   7969             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   7970             psource_frame = NULL;
   7971         }
   7972         if (pdest_frame) {
   7973             pdest_frame->nFilledLen = 0;
   7974             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
   7975                     (unsigned)NULL);
   7976             pdest_frame = NULL;
   7977         }
   7978     }
   7979 
   7980     if (!output_flush_progress && (buffer->nFilledLen > 0)) {
   7981         // set the default colorspace advised by client, since the bitstream may be
   7982         // devoid of colorspace-info.
   7983         if (m_enable_android_native_buffers) {
   7984             ColorSpace_t color_space = ITU_R_601;
   7985 
   7986         // Disabled ?
   7987         // WA for VP8. Vp8 encoder does not embed color-info (yet!).
   7988         // Encoding RGBA results in 601-LR for all resolutions.
   7989         // This conflicts with the client't defaults which are based on resolution.
   7990         //   Eg: 720p will be encoded as 601-LR. Client will say 709.
   7991         // Re-enable this code once vp8 encoder generates color-info and hence the
   7992         // decoder will be able to override with the correct source color.
   7993 #if 0
   7994             switch (m_client_color_space.sAspects.mPrimaries) {
   7995                 case ColorAspects::PrimariesBT601_6_625:
   7996                 case ColorAspects::PrimariesBT601_6_525:
   7997                 {
   7998                     color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
   7999                             ITU_R_601_FR : ITU_R_601;
   8000                     break;
   8001                 }
   8002                 case ColorAspects::PrimariesBT709_5:
   8003                 {
   8004                     color_space = ITU_R_709;
   8005                     break;
   8006                 }
   8007                 default:
   8008                 {
   8009                     break;
   8010                 }
   8011             }
   8012 #endif
   8013             DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
   8014                     color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   8015             set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr);
   8016         }
   8017         DEBUG_PRINT_LOW("Processing extradata");
   8018         handle_extradata(buffer);
   8019     }
   8020 
   8021 #ifdef OUTPUT_EXTRADATA_LOG
   8022     if (outputExtradataFile) {
   8023         int buf_index = buffer - m_out_mem_ptr;
   8024         OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
   8025 
   8026         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   8027         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   8028             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
   8029 
   8030         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
   8031             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
   8032                                     p_extra->nSize, p_extra->eType);
   8033             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   8034 
   8035             if (p_extra->eType == OMX_ExtraDataNone) {
   8036                 break;
   8037             }
   8038             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   8039         }
   8040     }
   8041 #endif
   8042 
   8043     /* For use buffer we need to copy the data */
   8044     if (!output_flush_progress) {
   8045         /* This is the error check for non-recoverable errros */
   8046         bool is_duplicate_ts_valid = true;
   8047         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   8048 
   8049         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   8050                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   8051                 output_capability == V4L2_PIX_FMT_DIVX ||
   8052                 output_capability == V4L2_PIX_FMT_DIVX_311)
   8053             is_duplicate_ts_valid = false;
   8054 
   8055         if ((output_capability == V4L2_PIX_FMT_H264 ||
   8056                 output_capability == V4L2_PIX_FMT_H264_MVC) &&
   8057                 is_interlaced) {
   8058             if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
   8059                 is_interlaced = false;
   8060             }
   8061         }
   8062 
   8063         if (buffer->nFilledLen > 0) {
   8064             time_stamp_dts.get_next_timestamp(buffer,
   8065                     is_interlaced && is_duplicate_ts_valid);
   8066             if (m_debug_timestamp) {
   8067                 {
   8068                     OMX_TICKS expected_ts = 0;
   8069                     m_timestamp_list.pop_min_ts(expected_ts);
   8070                     if (is_interlaced && is_duplicate_ts_valid) {
   8071                         m_timestamp_list.pop_min_ts(expected_ts);
   8072                     }
   8073                     DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   8074                             buffer->nTimeStamp, expected_ts);
   8075 
   8076                     if (buffer->nTimeStamp != expected_ts) {
   8077                         DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
   8078                     }
   8079                 }
   8080             }
   8081         }
   8082     }
   8083 
   8084     if (m_cb.FillBufferDone) {
   8085         if (buffer->nFilledLen > 0) {
   8086             if (arbitrary_bytes)
   8087                 adjust_timestamp(buffer->nTimeStamp);
   8088             else
   8089                 set_frame_rate(buffer->nTimeStamp);
   8090 
   8091             if (perf_flag) {
   8092                 if (!proc_frms) {
   8093                     dec_time.stop();
   8094                     latency = dec_time.processing_time_us() - latency;
   8095                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   8096                     dec_time.start();
   8097                     fps_metrics.start();
   8098                 }
   8099                 proc_frms++;
   8100                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8101                     OMX_U64 proc_time = 0;
   8102                     fps_metrics.stop();
   8103                     proc_time = fps_metrics.processing_time_us();
   8104                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
   8105                             (unsigned int)proc_frms, (float)proc_time / 1e6,
   8106                             (float)(1e6 * proc_frms) / proc_time);
   8107                     proc_frms = 0;
   8108                 }
   8109             }
   8110         }
   8111         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8112             prev_ts = LLONG_MAX;
   8113             rst_prev_ts = true;
   8114         }
   8115 
   8116         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   8117             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   8118              buffer->pPlatformPrivate)->entryList->entry;
   8119         DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   8120         OMX_BUFFERHEADERTYPE *il_buffer;
   8121         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   8122         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
   8123 
   8124         if (il_buffer && m_last_rendered_TS >= 0) {
   8125             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
   8126 
   8127             // Current frame can be send for rendering if
   8128             // (a) current FPS is <=  60
   8129             // (b) is the next frame after the frame with TS 0
   8130             // (c) is the first frame after seek
   8131             // (d) the delta TS b\w two consecutive frames is > 16 ms
   8132             // (e) its TS is equal to previous frame TS
   8133             // (f) if marked EOS
   8134 
   8135             if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
   8136                il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
   8137                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   8138                m_last_rendered_TS = il_buffer->nTimeStamp;
   8139             } else {
   8140                //mark for droping
   8141                buffer->nFilledLen = 0;
   8142             }
   8143 
   8144             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
   8145                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
   8146                               il_buffer->nTimeStamp,ts_delta);
   8147 
   8148             //above code makes sure that delta b\w two consecutive frames is not
   8149             //greater than 16ms, slow-mo feature, so cap fps to max 60
   8150             if (current_framerate > 60 ) {
   8151                 current_framerate = 60;
   8152             }
   8153         }
   8154 
   8155         // add current framerate to gralloc meta data
   8156         if (m_enable_android_native_buffers && m_out_mem_ptr) {
   8157             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8158             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8159                          UPDATE_REFRESH_RATE, (void*)&current_framerate);
   8160         }
   8161 
   8162         if (il_buffer) {
   8163             log_output_buffers(il_buffer);
   8164             if (dynamic_buf_mode) {
   8165                 unsigned int nPortIndex = 0;
   8166                 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8167 
   8168                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
   8169                 // to size of the handle. Do it _after_ log_output_buffers which
   8170                 // requires the respective sizes to be accurate.
   8171 
   8172                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   8173                 buffer->nFilledLen = buffer->nFilledLen ?
   8174                         sizeof(struct VideoDecoderOutputMetaData) : 0;
   8175 
   8176                 //Clear graphic buffer handles in dynamic mode
   8177                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
   8178                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   8179                     native_buffer[nPortIndex].privatehandle = NULL;
   8180                     native_buffer[nPortIndex].nativehandle = NULL;
   8181                 } else {
   8182                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
   8183                     return OMX_ErrorBadParameter;
   8184                 }
   8185             }
   8186             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   8187         } else {
   8188             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   8189             return OMX_ErrorBadParameter;
   8190         }
   8191         DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   8192     } else {
   8193         return OMX_ErrorBadParameter;
   8194     }
   8195 
   8196 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   8197     if (m_smoothstreaming_mode && m_out_mem_ptr) {
   8198         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8199         BufferDim_t dim;
   8200         private_handle_t *private_handle = NULL;
   8201         dim.sliceWidth = framesize.nWidth;
   8202         dim.sliceHeight = framesize.nHeight;
   8203         if (buf_index < drv_ctx.op_buf.actualcount &&
   8204             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   8205             native_buffer[buf_index].privatehandle)
   8206             private_handle = native_buffer[buf_index].privatehandle;
   8207         if (private_handle) {
   8208             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   8209                 dim.sliceWidth, dim.sliceHeight);
   8210             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   8211         }
   8212     }
   8213 #endif
   8214 
   8215     return OMX_ErrorNone;
   8216 }
   8217 
   8218 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   8219         OMX_BUFFERHEADERTYPE* buffer)
   8220 {
   8221 
   8222     int nBufferIndex = buffer - m_inp_mem_ptr;
   8223 
   8224     if (buffer == NULL || (nBufferIndex > (int)drv_ctx.ip_buf.actualcount)) {
   8225         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
   8226         return OMX_ErrorBadParameter;
   8227     }
   8228 
   8229     DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x",
   8230             buffer, buffer->pBuffer, buffer->nFlags);
   8231     pending_input_buffers--;
   8232 
   8233     if (arbitrary_bytes) {
   8234         if (pdest_frame == NULL && input_flush_progress == false) {
   8235             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
   8236             pdest_frame = buffer;
   8237             buffer->nFilledLen = 0;
   8238             buffer->nTimeStamp = LLONG_MAX;
   8239             push_input_buffer (hComp);
   8240         } else {
   8241             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
   8242             buffer->nFilledLen = 0;
   8243             if (!m_input_free_q.insert_entry((unsigned long)buffer,
   8244                         (unsigned)NULL, (unsigned)NULL)) {
   8245                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
   8246             }
   8247         }
   8248     } else if (m_cb.EmptyBufferDone) {
   8249         buffer->nFilledLen = 0;
   8250         if (input_use_buffer == true) {
   8251             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   8252         }
   8253 
   8254         /* Restore the FD that we over-wrote in ETB */
   8255         if (m_input_pass_buffer_fd) {
   8256             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
   8257         }
   8258 
   8259         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   8260     }
   8261     return OMX_ErrorNone;
   8262 }
   8263 
   8264 int omx_vdec::async_message_process (void *context, void* message)
   8265 {
   8266     omx_vdec* omx = NULL;
   8267     struct vdec_msginfo *vdec_msg = NULL;
   8268     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   8269     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   8270     struct vdec_output_frameinfo *output_respbuf = NULL;
   8271     int rc=1;
   8272     if (context == NULL || message == NULL) {
   8273         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
   8274         return -1;
   8275     }
   8276     vdec_msg = (struct vdec_msginfo *)message;
   8277 
   8278     omx = reinterpret_cast<omx_vdec*>(context);
   8279 
   8280     switch (vdec_msg->msgcode) {
   8281 
   8282         case VDEC_MSG_EVT_HW_ERROR:
   8283             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8284                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8285             break;
   8286 
   8287         case VDEC_MSG_EVT_HW_OVERLOAD:
   8288             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8289                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
   8290             break;
   8291 
   8292         case VDEC_MSG_EVT_HW_UNSUPPORTED:
   8293             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8294                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   8295             break;
   8296 
   8297         case VDEC_MSG_RESP_START_DONE:
   8298             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8299                     OMX_COMPONENT_GENERATE_START_DONE);
   8300             break;
   8301 
   8302         case VDEC_MSG_RESP_STOP_DONE:
   8303             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8304                     OMX_COMPONENT_GENERATE_STOP_DONE);
   8305             break;
   8306 
   8307         case VDEC_MSG_RESP_RESUME_DONE:
   8308             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8309                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   8310             break;
   8311 
   8312         case VDEC_MSG_RESP_PAUSE_DONE:
   8313             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8314                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   8315             break;
   8316 
   8317         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   8318             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8319                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   8320             break;
   8321         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   8322             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8323                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   8324             break;
   8325         case VDEC_MSG_RESP_INPUT_FLUSHED:
   8326         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   8327 
   8328             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   8329                vdec_msg->msgdata.input_frame_clientdata; */
   8330 
   8331             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   8332             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
   8333                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
   8334                 omxhdr = NULL;
   8335                 vdec_msg->status_code = VDEC_S_EFATAL;
   8336                 break;
   8337 
   8338             }
   8339             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
   8340 
   8341             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   8342                 DEBUG_PRINT_HIGH("Unsupported input");
   8343                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8344                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8345             }
   8346             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   8347                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   8348                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   8349             }
   8350             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   8351 
   8352                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
   8353                 android_atomic_dec(&omx->m_queued_codec_config_count);
   8354                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
   8355                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
   8356                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
   8357                     sem_post(&omx->m_safe_flush);
   8358                 }
   8359             }
   8360             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME ||
   8361                 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   8362                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   8363             }
   8364             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
   8365                     OMX_COMPONENT_GENERATE_EBD);
   8366             break;
   8367         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   8368             int64_t *timestamp;
   8369             timestamp = (int64_t *) malloc(sizeof(int64_t));
   8370             if (timestamp) {
   8371                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   8372                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
   8373                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   8374                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
   8375                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
   8376             }
   8377             break;
   8378         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   8379         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   8380 
   8381            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   8382 
   8383            if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL ||
   8384                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
   8385                omxhdr = NULL;
   8386                vdec_msg->status_code = VDEC_S_EFATAL;
   8387                break;
   8388            }
   8389 
   8390            omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index;
   8391 
   8392             DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
   8393                     omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
   8394                     vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
   8395                     (unsigned int)vdec_msg->msgdata.output_frame.len,
   8396                     vdec_msg->msgdata.output_frame.framesize.left,
   8397                     vdec_msg->msgdata.output_frame.framesize.top,
   8398                     vdec_msg->msgdata.output_frame.framesize.right,
   8399                     vdec_msg->msgdata.output_frame.framesize.bottom);
   8400 
   8401             if (omxhdr && omxhdr->pOutputPortPrivate &&
   8402                     ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
   8403                     (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   8404                       - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
   8405 
   8406                 if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   8407                     omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   8408                     omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   8409                     omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   8410                     omxhdr->nFlags = 0;
   8411 
   8412                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
   8413                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   8414                         //rc = -1;
   8415                     }
   8416                     if (omxhdr->nFilledLen) {
   8417                         omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   8418                     }
   8419                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   8420                         omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   8421                     } else {
   8422                         omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   8423                     }
   8424                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   8425                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8426                     }
   8427                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   8428                         omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   8429                     }
   8430 
   8431                     if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
   8432                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
   8433                     }
   8434 
   8435                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   8436                          omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
   8437                          DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   8438                                     omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   8439                     }
   8440 
   8441                     if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   8442                             !omx->output_flush_progress &&
   8443                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   8444                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
   8445                         unsigned int index = v4l2_buf_ptr->index;
   8446                         unsigned int extra_idx = EXTRADATA_IDX(omx->drv_ctx.num_planes);
   8447                         struct v4l2_plane *plane = v4l2_buf_ptr->m.planes;
   8448                         omx->time_stamp_dts.remove_time_stamp(
   8449                                 omxhdr->nTimeStamp,
   8450                                 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   8451                                 ?true:false);
   8452                         plane[0].bytesused = 0;
   8453                         plane[0].m.userptr =
   8454                             (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].bufferaddr -
   8455                             (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].offset;
   8456                         plane[0].reserved[0] = omx->drv_ctx.ptr_outputbuffer[index].pmem_fd;
   8457                         plane[0].reserved[1] = omx->drv_ctx.ptr_outputbuffer[index].offset;
   8458                         plane[0].data_offset = 0;
   8459                         v4l2_buf_ptr->flags = 0x0;
   8460                         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   8461                             plane[extra_idx].bytesused = 0;
   8462                             plane[extra_idx].length = omx->drv_ctx.extradata_info.buffer_size;
   8463                             plane[extra_idx].m.userptr = (long unsigned int) (omx->drv_ctx.extradata_info.uaddr + index * omx->drv_ctx.extradata_info.buffer_size);
   8464 #ifdef USE_ION
   8465                             plane[extra_idx].reserved[0] = omx->drv_ctx.extradata_info.ion.fd_ion_data.fd;
   8466 #endif
   8467                             plane[extra_idx].reserved[1] = v4l2_buf_ptr->index * omx->drv_ctx.extradata_info.buffer_size;
   8468                             plane[extra_idx].data_offset = 0;
   8469                         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   8470                             DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   8471                             return -1;
   8472                         }
   8473 
   8474                          DEBUG_PRINT_LOW("SENDING FTB TO F/W from async_message_process - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   8475                                plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], omx->output_flush_progress);
   8476                         if(ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_QBUF, v4l2_buf_ptr)) {
   8477                             DEBUG_PRINT_ERROR("Failed to queue buffer back to driver: %d, %d, %d", v4l2_buf_ptr->length, v4l2_buf_ptr->m.planes[0].reserved[0], v4l2_buf_ptr->m.planes[1].reserved[0]);
   8478                             return -1;
   8479                         }
   8480                         break;
   8481                     }
   8482                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   8483                         omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   8484                     }
   8485                     vdec_msg->msgdata.output_frame.bufferaddr =
   8486                         omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   8487 
   8488                     /* Post event if resolution OR crop changed */
   8489                     /* filled length will be changed if resolution changed */
   8490                     /* Crop parameters can be changed even without resolution change */
   8491                     if (omxhdr->nFilledLen
   8492                         && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
   8493                         || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
   8494                         || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
   8495                         || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
   8496                         || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
   8497                         || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
   8498                         || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
   8499 
   8500                         DEBUG_PRINT_HIGH("Paramters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
   8501                                 omx->prev_n_filled_len,
   8502                                 omx->drv_ctx.video_resolution.frame_width,
   8503                                 omx->drv_ctx.video_resolution.frame_height,
   8504                                 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
   8505                                 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
   8506                                 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
   8507                                 vdec_msg->msgdata.output_frame.picsize.frame_height,
   8508                                 vdec_msg->msgdata.output_frame.framesize.left,
   8509                                 vdec_msg->msgdata.output_frame.framesize.top,
   8510                                 vdec_msg->msgdata.output_frame.framesize.right,
   8511                                 vdec_msg->msgdata.output_frame.framesize.bottom);
   8512 
   8513                         omx->drv_ctx.video_resolution.frame_width =
   8514                                 vdec_msg->msgdata.output_frame.picsize.frame_width;
   8515                         omx->drv_ctx.video_resolution.frame_height =
   8516                                 vdec_msg->msgdata.output_frame.picsize.frame_height;
   8517                         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   8518                             omx->drv_ctx.video_resolution.stride =
   8519                                 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
   8520                             omx->drv_ctx.video_resolution.scan_lines =
   8521                                 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
   8522                         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   8523                             omx->drv_ctx.video_resolution.stride =
   8524                                 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
   8525                             omx->drv_ctx.video_resolution.scan_lines =
   8526                                 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
   8527                         }
   8528 
   8529                         memcpy(&omx->drv_ctx.frame_size,
   8530                                 &vdec_msg->msgdata.output_frame.framesize,
   8531                                 sizeof(struct vdec_framesize));
   8532 
   8533                         omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   8534                                 OMX_IndexConfigCommonOutputCrop,
   8535                                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   8536                     }
   8537 
   8538                     if (omxhdr->nFilledLen)
   8539                         omx->prev_n_filled_len = omxhdr->nFilledLen;
   8540 
   8541                     output_respbuf = (struct vdec_output_frameinfo *)\
   8542                              omxhdr->pOutputPortPrivate;
   8543                     if (!output_respbuf) {
   8544                       DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
   8545                       return -1;
   8546                     }
   8547                     output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   8548                     output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   8549 
   8550                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   8551                         output_respbuf->pic_type = PICTURE_TYPE_I;
   8552                     }
   8553                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   8554                         output_respbuf->pic_type = PICTURE_TYPE_P;
   8555                     }
   8556                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   8557                         output_respbuf->pic_type = PICTURE_TYPE_B;
   8558                     }
   8559                     if (omxhdr && omxhdr->nFilledLen) {
   8560                         omx->request_perf_level(VIDC_NOMINAL);
   8561                     }
   8562                     if (omx->output_use_buffer && omxhdr->pBuffer &&
   8563                         vdec_msg->msgdata.output_frame.bufferaddr)
   8564                         memcpy ( omxhdr->pBuffer, (void *)
   8565                                 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   8566                                  (unsigned long)vdec_msg->msgdata.output_frame.offset),
   8567                                 vdec_msg->msgdata.output_frame.len);
   8568                 } else {
   8569                     DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
   8570                             (unsigned int)vdec_msg->msgdata.output_frame.len,
   8571                             omxhdr->nAllocLen, omx->prev_n_filled_len);
   8572                     omxhdr->nFilledLen = 0;
   8573                 }
   8574 
   8575                 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
   8576                         OMX_COMPONENT_GENERATE_FBD);
   8577 
   8578             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
   8579                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
   8580                         OMX_COMPONENT_GENERATE_EOS_DONE);
   8581             } else {
   8582                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   8583                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8584             }
   8585             break;
   8586         case VDEC_MSG_EVT_CONFIG_CHANGED:
   8587             DEBUG_PRINT_HIGH("Port settings changed");
   8588             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   8589             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   8590             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   8591                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   8592             omx->request_perf_level(VIDC_NOMINAL);
   8593             break;
   8594         default:
   8595             break;
   8596     }
   8597     return rc;
   8598 }
   8599 
   8600 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   8601         OMX_HANDLETYPE hComp,
   8602         OMX_BUFFERHEADERTYPE *buffer
   8603         )
   8604 {
   8605     unsigned address,p2,id;
   8606     DEBUG_PRINT_LOW("Empty this arbitrary");
   8607 
   8608     if (buffer == NULL) {
   8609         return OMX_ErrorBadParameter;
   8610     }
   8611     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   8612     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
   8613             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
   8614 
   8615     /* return zero length and not an EOS buffer */
   8616     /* return buffer if input flush in progress */
   8617     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   8618                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   8619         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
   8620         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   8621         return OMX_ErrorNone;
   8622     }
   8623 
   8624     if (psource_frame == NULL) {
   8625         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   8626         psource_frame = buffer;
   8627         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
   8628         push_input_buffer (hComp);
   8629     } else {
   8630         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
   8631         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
   8632                     (unsigned)NULL)) {
   8633             return OMX_ErrorBadParameter;
   8634         }
   8635     }
   8636 
   8637     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   8638         codec_config_flag = false;
   8639     }
   8640     return OMX_ErrorNone;
   8641 }
   8642 
   8643 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   8644 {
   8645     unsigned long address,p2,id;
   8646     OMX_ERRORTYPE ret = OMX_ErrorNone;
   8647 
   8648     if (pdest_frame == NULL || psource_frame == NULL) {
   8649         /*Check if we have a destination buffer*/
   8650         if (pdest_frame == NULL) {
   8651             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
   8652             if (m_input_free_q.m_size) {
   8653                 m_input_free_q.pop_entry(&address,&p2,&id);
   8654                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   8655                 pdest_frame->nFilledLen = 0;
   8656                 pdest_frame->nTimeStamp = LLONG_MAX;
   8657                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
   8658             }
   8659         }
   8660 
   8661         /*Check if we have a destination buffer*/
   8662         if (psource_frame == NULL) {
   8663             DEBUG_PRINT_LOW("Get a source buffer from the queue");
   8664             if (m_input_pending_q.m_size) {
   8665                 m_input_pending_q.pop_entry(&address,&p2,&id);
   8666                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   8667                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   8668                         psource_frame->nTimeStamp);
   8669                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   8670                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   8671 
   8672             }
   8673         }
   8674 
   8675     }
   8676 
   8677     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   8678         switch (codec_type_parse) {
   8679             case CODEC_TYPE_MPEG4:
   8680             case CODEC_TYPE_H263:
   8681             case CODEC_TYPE_MPEG2:
   8682                 ret =  push_input_sc_codec(hComp);
   8683                 break;
   8684             case CODEC_TYPE_H264:
   8685                 ret = push_input_h264(hComp);
   8686                 break;
   8687             case CODEC_TYPE_HEVC:
   8688                 ret = push_input_hevc(hComp);
   8689                 break;
   8690             case CODEC_TYPE_VC1:
   8691                 ret = push_input_vc1(hComp);
   8692                 break;
   8693             default:
   8694                 break;
   8695         }
   8696         if (ret != OMX_ErrorNone) {
   8697             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
   8698             omx_report_error ();
   8699             break;
   8700         }
   8701     }
   8702 
   8703     return ret;
   8704 }
   8705 
   8706 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   8707 {
   8708     OMX_U32 partial_frame = 1;
   8709     OMX_BOOL generate_ebd = OMX_TRUE;
   8710     unsigned long address = 0, p2 = 0, id = 0;
   8711 
   8712     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
   8713             psource_frame,psource_frame->nTimeStamp);
   8714     if (m_frame_parser.parse_sc_frame(psource_frame,
   8715                 pdest_frame,&partial_frame) == -1) {
   8716         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   8717         return OMX_ErrorBadParameter;
   8718     }
   8719 
   8720     if (partial_frame == 0) {
   8721         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
   8722                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
   8723 
   8724 
   8725         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
   8726         /*First Parsed buffer will have only header Hence skip*/
   8727         if (frame_count == 0) {
   8728             DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
   8729 
   8730             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   8731                     codec_type_parse == CODEC_TYPE_DIVX) {
   8732                 mp4StreamType psBits;
   8733                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   8734                 psBits.numBytes = pdest_frame->nFilledLen;
   8735                 mp4_headerparser.parseHeader(&psBits);
   8736             }
   8737 
   8738             frame_count++;
   8739         } else {
   8740             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   8741             if (pdest_frame->nFilledLen) {
   8742                 /*Push the frame to the Decoder*/
   8743                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8744                     return OMX_ErrorBadParameter;
   8745                 }
   8746                 frame_count++;
   8747                 pdest_frame = NULL;
   8748 
   8749                 if (m_input_free_q.m_size) {
   8750                     m_input_free_q.pop_entry(&address,&p2,&id);
   8751                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   8752                     pdest_frame->nFilledLen = 0;
   8753                 }
   8754             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   8755                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
   8756                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
   8757                         (unsigned)NULL);
   8758                 pdest_frame = NULL;
   8759             }
   8760         }
   8761     } else {
   8762         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
   8763         /*Check if Destination Buffer is full*/
   8764         if (pdest_frame->nAllocLen ==
   8765                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   8766             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
   8767             return OMX_ErrorStreamCorrupt;
   8768         }
   8769     }
   8770 
   8771     if (psource_frame->nFilledLen == 0) {
   8772         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   8773             if (pdest_frame) {
   8774                 pdest_frame->nFlags |= psource_frame->nFlags;
   8775                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
   8776                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   8777                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   8778                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   8779                 /*Push the frame to the Decoder*/
   8780                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8781                     return OMX_ErrorBadParameter;
   8782                 }
   8783                 frame_count++;
   8784                 pdest_frame = NULL;
   8785             } else {
   8786                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
   8787                 generate_ebd = OMX_FALSE;
   8788             }
   8789         }
   8790         if (generate_ebd) {
   8791             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
   8792             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   8793             psource_frame = NULL;
   8794 
   8795             if (m_input_pending_q.m_size) {
   8796                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   8797                 m_input_pending_q.pop_entry(&address,&p2,&id);
   8798                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   8799                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   8800                         psource_frame->nTimeStamp);
   8801                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   8802                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   8803             }
   8804         }
   8805     }
   8806     return OMX_ErrorNone;
   8807 }
   8808 
   8809 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   8810 {
   8811     OMX_U32 partial_frame = 1;
   8812     unsigned long address = 0, p2 = 0, id = 0;
   8813     OMX_BOOL isNewFrame = OMX_FALSE;
   8814     OMX_BOOL generate_ebd = OMX_TRUE;
   8815 
   8816     if (h264_scratch.pBuffer == NULL) {
   8817         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
   8818         return OMX_ErrorBadParameter;
   8819     }
   8820     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
   8821             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
   8822     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
   8823     if (h264_scratch.nFilledLen && look_ahead_nal) {
   8824         look_ahead_nal = false;
   8825         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8826                 h264_scratch.nFilledLen) {
   8827             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8828                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8829             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8830             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
   8831             h264_scratch.nFilledLen = 0;
   8832         } else {
   8833             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
   8834             return OMX_ErrorBadParameter;
   8835         }
   8836     }
   8837 
   8838     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   8839        in EOS flag getting associated with the destination
   8840     */
   8841     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   8842             pdest_frame->nFilledLen) {
   8843         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   8844         generate_ebd = OMX_FALSE;
   8845     }
   8846 
   8847     if (nal_length == 0) {
   8848         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
   8849         if (m_frame_parser.parse_sc_frame(psource_frame,
   8850                     &h264_scratch,&partial_frame) == -1) {
   8851             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   8852             return OMX_ErrorBadParameter;
   8853         }
   8854     } else {
   8855         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   8856         if (m_frame_parser.parse_h264_nallength(psource_frame,
   8857                     &h264_scratch,&partial_frame) == -1) {
   8858             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   8859             return OMX_ErrorBadParameter;
   8860         }
   8861     }
   8862 
   8863     if (partial_frame == 0) {
   8864         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   8865             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   8866             nal_count++;
   8867             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   8868             h264_scratch.nFlags = psource_frame->nFlags;
   8869         } else {
   8870             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
   8871             if (h264_scratch.nFilledLen) {
   8872                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   8873                         NALU_TYPE_SPS);
   8874 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   8875                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   8876                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   8877                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   8878                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   8879                     // If timeinfo is present frame info from SEI is already processed
   8880                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   8881                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   8882 #endif
   8883                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   8884                 nal_count++;
   8885                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   8886                     pdest_frame->nTimeStamp = h264_last_au_ts;
   8887                     pdest_frame->nFlags = h264_last_au_flags;
   8888 #ifdef PANSCAN_HDLR
   8889                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   8890                         h264_parser->update_panscan_data(h264_last_au_ts);
   8891 #endif
   8892                 }
   8893                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   8894                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   8895                     h264_last_au_ts = h264_scratch.nTimeStamp;
   8896                     h264_last_au_flags = h264_scratch.nFlags;
   8897 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   8898                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   8899                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   8900                         if (!VALID_TS(h264_last_au_ts))
   8901                             h264_last_au_ts = ts_in_sei;
   8902                     }
   8903 #endif
   8904                 } else
   8905                     h264_last_au_ts = LLONG_MAX;
   8906             }
   8907 
   8908             if (!isNewFrame) {
   8909                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8910                         h264_scratch.nFilledLen) {
   8911                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
   8912                             (unsigned int)h264_scratch.nFilledLen);
   8913                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8914                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8915                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8916                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   8917                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8918                     h264_scratch.nFilledLen = 0;
   8919                 } else {
   8920                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
   8921                     return OMX_ErrorBadParameter;
   8922                 }
   8923             } else if(h264_scratch.nFilledLen) {
   8924                 look_ahead_nal = true;
   8925                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
   8926                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   8927                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   8928                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   8929 
   8930                 if (pdest_frame->nFilledLen == 0) {
   8931                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
   8932                     look_ahead_nal = false;
   8933                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8934                             h264_scratch.nFilledLen) {
   8935                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8936                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8937                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8938                         h264_scratch.nFilledLen = 0;
   8939                     } else {
   8940                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
   8941                         return OMX_ErrorBadParameter;
   8942                     }
   8943                 } else {
   8944                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   8945                         DEBUG_PRINT_LOW("Reset the EOS Flag");
   8946                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   8947                     }
   8948                     /*Push the frame to the Decoder*/
   8949                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8950                         return OMX_ErrorBadParameter;
   8951                     }
   8952                     //frame_count++;
   8953                     pdest_frame = NULL;
   8954                     if (m_input_free_q.m_size) {
   8955                         m_input_free_q.pop_entry(&address,&p2,&id);
   8956                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   8957                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
   8958                         pdest_frame->nFilledLen = 0;
   8959                         pdest_frame->nFlags = 0;
   8960                         pdest_frame->nTimeStamp = LLONG_MAX;
   8961                     }
   8962                 }
   8963             }
   8964         }
   8965     } else {
   8966         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
   8967         /*Check if Destination Buffer is full*/
   8968         if (h264_scratch.nAllocLen ==
   8969                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   8970             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   8971             return OMX_ErrorStreamCorrupt;
   8972         }
   8973     }
   8974 
   8975     if (!psource_frame->nFilledLen) {
   8976         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
   8977 
   8978         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   8979             if (pdest_frame) {
   8980                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   8981                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8982                         h264_scratch.nFilledLen) {
   8983                     if(pdest_frame->nFilledLen == 0) {
   8984                         /* No residual frame from before, send whatever
   8985                          * we have left */
   8986                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8987                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   8988                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8989                         h264_scratch.nFilledLen = 0;
   8990                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   8991                     } else {
   8992                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   8993                         if(!isNewFrame) {
   8994                             /* Have a residual frame, but we know that the
   8995                              * AU in this frame is belonging to whatever
   8996                              * frame we had left over.  So append it */
   8997                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8998                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8999                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9000                              h264_scratch.nFilledLen = 0;
   9001                              if (h264_last_au_ts != LLONG_MAX)
   9002                                  pdest_frame->nTimeStamp = h264_last_au_ts;
   9003                         } else {
   9004                             /* Completely new frame, let's just push what
   9005                              * we have now.  The resulting EBD would trigger
   9006                              * another push */
   9007                             generate_ebd = OMX_FALSE;
   9008                             pdest_frame->nTimeStamp = h264_last_au_ts;
   9009                             h264_last_au_ts = h264_scratch.nTimeStamp;
   9010                         }
   9011                     }
   9012                 } else {
   9013                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
   9014                     return OMX_ErrorBadParameter;
   9015                 }
   9016 
   9017                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   9018                 if(generate_ebd == OMX_TRUE) {
   9019                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9020                 }
   9021 
   9022                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
   9023                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9024                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
   9025 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9026                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9027                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   9028                     if (!VALID_TS(pdest_frame->nTimeStamp))
   9029                         pdest_frame->nTimeStamp = ts_in_sei;
   9030                 }
   9031 #endif
   9032                 /*Push the frame to the Decoder*/
   9033                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9034                     return OMX_ErrorBadParameter;
   9035                 }
   9036                 frame_count++;
   9037                 pdest_frame = NULL;
   9038             } else {
   9039                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9040                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9041                 generate_ebd = OMX_FALSE;
   9042             }
   9043         }
   9044     }
   9045     if (generate_ebd && !psource_frame->nFilledLen) {
   9046         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9047         psource_frame = NULL;
   9048         if (m_input_pending_q.m_size) {
   9049             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9050             m_input_pending_q.pop_entry(&address,&p2,&id);
   9051             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9052             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
   9053                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9054         }
   9055     }
   9056     return OMX_ErrorNone;
   9057 }
   9058 
   9059 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
   9060 {
   9061     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9062     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
   9063         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
   9064         if (pDst->nTimeStamp == LLONG_MAX) {
   9065             pDst->nTimeStamp = pSrc->nTimeStamp;
   9066             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
   9067         }
   9068         pDst->nFilledLen += pSrc->nFilledLen;
   9069         pSrc->nFilledLen = 0;
   9070     } else {
   9071         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
   9072         rc = OMX_ErrorBadParameter;
   9073     }
   9074     return rc;
   9075 }
   9076 
   9077 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
   9078 {
   9079     OMX_U32 partial_frame = 1;
   9080     unsigned long address,p2,id;
   9081     OMX_BOOL isNewFrame = OMX_FALSE;
   9082     OMX_BOOL generate_ebd = OMX_TRUE;
   9083     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9084     if (h264_scratch.pBuffer == NULL) {
   9085         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
   9086         return OMX_ErrorBadParameter;
   9087     }
   9088 
   9089     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
   9090             pdest_frame nFilledLen %u nTimeStamp %lld",
   9091             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9092 
   9093     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9094         look_ahead_nal = false;
   9095         rc = copy_buffer(pdest_frame, &h264_scratch);
   9096         if (rc != OMX_ErrorNone) {
   9097             return rc;
   9098         }
   9099     }
   9100 
   9101     if (nal_length == 0) {
   9102         if (m_frame_parser.parse_sc_frame(psource_frame,
   9103                     &h264_scratch,&partial_frame) == -1) {
   9104             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9105             return OMX_ErrorBadParameter;
   9106         }
   9107     } else {
   9108         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
   9109         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9110                     &h264_scratch,&partial_frame) == -1) {
   9111             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9112             return OMX_ErrorBadParameter;
   9113         }
   9114     }
   9115 
   9116     if (partial_frame == 0) {
   9117         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9118             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9119             nal_count++;
   9120             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9121             h264_scratch.nFlags = psource_frame->nFlags;
   9122         } else {
   9123             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
   9124             if (h264_scratch.nFilledLen) {
   9125                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
   9126                 nal_count++;
   9127             }
   9128 
   9129             if (!isNewFrame) {
   9130                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
   9131                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
   9132                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
   9133                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9134                 rc = copy_buffer(pdest_frame, &h264_scratch);
   9135                 if (rc != OMX_ErrorNone) {
   9136                     return rc;
   9137                 }
   9138             } else {
   9139                 look_ahead_nal = true;
   9140                 if (pdest_frame->nFilledLen == 0) {
   9141                     look_ahead_nal = false;
   9142                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
   9143                     rc = copy_buffer(pdest_frame, &h264_scratch);
   9144                     if (rc != OMX_ErrorNone) {
   9145                         return OMX_ErrorBadParameter;
   9146                     }
   9147                 } else {
   9148                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   9149                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9150                     }
   9151                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
   9152                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
   9153                             nFilledLen %u nTimeStamp %lld",
   9154                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
   9155                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
   9156                             h264_scratch.nTimeStamp);
   9157                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   9158                         return OMX_ErrorBadParameter;
   9159                     }
   9160                     pdest_frame = NULL;
   9161                     if (m_input_free_q.m_size) {
   9162                         m_input_free_q.pop_entry(&address, &p2, &id);
   9163                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9164                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
   9165                         pdest_frame->nFilledLen = 0;
   9166                         pdest_frame->nFlags = 0;
   9167                         pdest_frame->nTimeStamp = LLONG_MAX;
   9168                     }
   9169                 }
   9170             }
   9171         }
   9172     } else {
   9173         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
   9174                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
   9175                 nFilledLen %u nTimeStamp %lld",
   9176                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
   9177                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
   9178                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
   9179 
   9180         if (h264_scratch.nAllocLen ==
   9181                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   9182             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   9183             return OMX_ErrorStreamCorrupt;
   9184         }
   9185     }
   9186 
   9187     if (!psource_frame->nFilledLen) {
   9188         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
   9189         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9190             if (pdest_frame) {
   9191                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   9192                 rc = copy_buffer(pdest_frame, &h264_scratch);
   9193                 if ( rc != OMX_ErrorNone ) {
   9194                     return rc;
   9195                 }
   9196                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   9197                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9198                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
   9199                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9200                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   9201                     return OMX_ErrorBadParameter;
   9202                 }
   9203                 frame_count++;
   9204                 pdest_frame = NULL;
   9205             } else {
   9206                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9207                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9208                 generate_ebd = OMX_FALSE;
   9209             }
   9210         }
   9211     }
   9212 
   9213     if (generate_ebd && !psource_frame->nFilledLen) {
   9214         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
   9215         psource_frame = NULL;
   9216         if (m_input_pending_q.m_size) {
   9217             m_input_pending_q.pop_entry(&address, &p2, &id);
   9218             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   9219             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
   9220                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
   9221         }
   9222     }
   9223     return OMX_ErrorNone;
   9224 }
   9225 
   9226 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp)
   9227 {
   9228     OMX_U8 *buf, *pdest;
   9229     OMX_U32 partial_frame = 1;
   9230     OMX_U32 buf_len, dest_len;
   9231 
   9232     if (first_frame == 0) {
   9233         first_frame = 1;
   9234         DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
   9235         if (!m_vendor_config.pData) {
   9236             DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
   9237             buf = psource_frame->pBuffer;
   9238             buf_len = psource_frame->nFilledLen;
   9239 
   9240             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   9241                     VC1_SP_MP_START_CODE) {
   9242                 m_vc1_profile = VC1_SP_MP_RCV;
   9243             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   9244                 m_vc1_profile = VC1_AP;
   9245             } else {
   9246                 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
   9247                 return OMX_ErrorStreamCorrupt;
   9248             }
   9249         } else {
   9250             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   9251                 pdest_frame->nOffset;
   9252             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   9253                     pdest_frame->nOffset);
   9254 
   9255             if (dest_len < m_vendor_config.nDataSize) {
   9256                 DEBUG_PRINT_ERROR("Destination buffer full");
   9257                 return OMX_ErrorBadParameter;
   9258             } else {
   9259                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   9260                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   9261             }
   9262         }
   9263     }
   9264 
   9265     switch (m_vc1_profile) {
   9266         case VC1_AP:
   9267             DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
   9268             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   9269                 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
   9270                 return OMX_ErrorBadParameter;
   9271             }
   9272             break;
   9273 
   9274         case VC1_SP_MP_RCV:
   9275         default:
   9276             DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
   9277             return OMX_ErrorBadParameter;
   9278     }
   9279     return OMX_ErrorNone;
   9280 }
   9281 
   9282 #ifndef USE_ION
   9283 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   9284         OMX_U32 alignment)
   9285 {
   9286     struct pmem_allocation allocation;
   9287     allocation.size = buffer_size;
   9288     allocation.align = clip2(alignment);
   9289     if (allocation.align < 4096) {
   9290         allocation.align = 4096;
   9291     }
   9292     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   9293         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
   9294                 allocation.align, allocation.size);
   9295         return false;
   9296     }
   9297     return true;
   9298 }
   9299 #endif
   9300 #ifdef USE_ION
   9301 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   9302         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   9303         struct ion_fd_data *fd_data, int flag)
   9304 {
   9305     int fd = -EINVAL;
   9306     int rc = -EINVAL;
   9307     int ion_dev_flag;
   9308     struct vdec_ion ion_buf_info;
   9309     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   9310         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
   9311         return -EINVAL;
   9312     }
   9313     ion_dev_flag = O_RDONLY;
   9314     fd = open (MEM_DEVICE, ion_dev_flag);
   9315     if (fd < 0) {
   9316         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
   9317         return fd;
   9318     }
   9319 
   9320     alloc_data->flags = flag;
   9321     alloc_data->len = buffer_size;
   9322     alloc_data->align = clip2(alignment);
   9323     if (alloc_data->align < 4096) {
   9324         alloc_data->align = 4096;
   9325     }
   9326 
   9327     alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   9328     if (secure_mode && (alloc_data->flags & ION_SECURE)) {
   9329         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   9330     }
   9331 
   9332     /* Use secure display cma heap for obvious reasons. */
   9333     if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
   9334         alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
   9335     }
   9336 
   9337     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   9338     if (rc || !alloc_data->handle) {
   9339         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
   9340         alloc_data->handle = 0;
   9341         close(fd);
   9342         fd = -ENOMEM;
   9343         return fd;
   9344     }
   9345     fd_data->handle = alloc_data->handle;
   9346     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   9347     if (rc) {
   9348         DEBUG_PRINT_ERROR("ION MAP failed ");
   9349         ion_buf_info.ion_alloc_data = *alloc_data;
   9350         ion_buf_info.ion_device_fd = fd;
   9351         ion_buf_info.fd_ion_data = *fd_data;
   9352         free_ion_memory(&ion_buf_info);
   9353         fd_data->fd =-1;
   9354         fd = -ENOMEM;
   9355     }
   9356 
   9357     return fd;
   9358 }
   9359 
   9360 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   9361 {
   9362 
   9363     if (!buf_ion_info) {
   9364         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
   9365         return;
   9366     }
   9367     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   9368                 &buf_ion_info->ion_alloc_data.handle)) {
   9369         DEBUG_PRINT_ERROR("ION: free failed" );
   9370     }
   9371     close(buf_ion_info->ion_device_fd);
   9372     buf_ion_info->ion_device_fd = -1;
   9373     buf_ion_info->ion_alloc_data.handle = 0;
   9374     buf_ion_info->fd_ion_data.fd = -1;
   9375 }
   9376 #endif
   9377 void omx_vdec::free_output_buffer_header()
   9378 {
   9379     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
   9380     output_use_buffer = false;
   9381     ouput_egl_buffers = false;
   9382 
   9383     if (m_out_mem_ptr) {
   9384         free (m_out_mem_ptr);
   9385         m_out_mem_ptr = NULL;
   9386     }
   9387 
   9388     if (m_platform_list) {
   9389         free(m_platform_list);
   9390         m_platform_list = NULL;
   9391     }
   9392 
   9393     if (drv_ctx.ptr_respbuffer) {
   9394         free (drv_ctx.ptr_respbuffer);
   9395         drv_ctx.ptr_respbuffer = NULL;
   9396     }
   9397     if (drv_ctx.ptr_outputbuffer) {
   9398         free (drv_ctx.ptr_outputbuffer);
   9399         drv_ctx.ptr_outputbuffer = NULL;
   9400     }
   9401 #ifdef USE_ION
   9402     if (drv_ctx.op_buf_ion_info) {
   9403         DEBUG_PRINT_LOW("Free o/p ion context");
   9404         free(drv_ctx.op_buf_ion_info);
   9405         drv_ctx.op_buf_ion_info = NULL;
   9406     }
   9407 #endif
   9408     buf_ref_remove();
   9409 }
   9410 
   9411 void omx_vdec::free_input_buffer_header()
   9412 {
   9413     input_use_buffer = false;
   9414     if (arbitrary_bytes) {
   9415         if (m_inp_heap_ptr) {
   9416             DEBUG_PRINT_LOW("Free input Heap Pointer");
   9417             free (m_inp_heap_ptr);
   9418             m_inp_heap_ptr = NULL;
   9419         }
   9420 
   9421         if (m_phdr_pmem_ptr) {
   9422             DEBUG_PRINT_LOW("Free input pmem header Pointer");
   9423             free (m_phdr_pmem_ptr);
   9424             m_phdr_pmem_ptr = NULL;
   9425         }
   9426     }
   9427     if (m_inp_mem_ptr) {
   9428         DEBUG_PRINT_LOW("Free input pmem Pointer area");
   9429         free (m_inp_mem_ptr);
   9430         m_inp_mem_ptr = NULL;
   9431     }
   9432     /* We just freed all the buffer headers, every thing in m_input_free_q,
   9433      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
   9434     while (m_input_free_q.m_size) {
   9435         unsigned long address, p2, id;
   9436         m_input_free_q.pop_entry(&address, &p2, &id);
   9437     }
   9438     while (m_input_pending_q.m_size) {
   9439         unsigned long address, p2, id;
   9440         m_input_pending_q.pop_entry(&address, &p2, &id);
   9441     }
   9442     pdest_frame = NULL;
   9443     psource_frame = NULL;
   9444     if (drv_ctx.ptr_inputbuffer) {
   9445         DEBUG_PRINT_LOW("Free Driver Context pointer");
   9446         free (drv_ctx.ptr_inputbuffer);
   9447         drv_ctx.ptr_inputbuffer = NULL;
   9448     }
   9449 #ifdef USE_ION
   9450     if (drv_ctx.ip_buf_ion_info) {
   9451         DEBUG_PRINT_LOW("Free ion context");
   9452         free(drv_ctx.ip_buf_ion_info);
   9453         drv_ctx.ip_buf_ion_info = NULL;
   9454     }
   9455 #endif
   9456 }
   9457 
   9458 int omx_vdec::stream_off(OMX_U32 port)
   9459 {
   9460     enum v4l2_buf_type btype;
   9461     int rc = 0;
   9462     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   9463 
   9464     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   9465         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9466         v4l2_port = OUTPUT_PORT;
   9467     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   9468         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9469         v4l2_port = CAPTURE_PORT;
   9470     } else if (port == OMX_ALL) {
   9471         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   9472         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   9473 
   9474         if (!rc_input)
   9475             return rc_input;
   9476         else
   9477             return rc_output;
   9478     }
   9479 
   9480     if (!streaming[v4l2_port]) {
   9481         // already streamed off, warn and move on
   9482         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   9483                 " which is already streamed off", v4l2_port);
   9484         return 0;
   9485     }
   9486 
   9487     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   9488 
   9489     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   9490     if (rc) {
   9491         /*TODO: How to handle this case */
   9492         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
   9493     } else {
   9494         streaming[v4l2_port] = false;
   9495     }
   9496 
   9497     return rc;
   9498 }
   9499 
   9500 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   9501 {
   9502     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9503     struct v4l2_requestbuffers bufreq;
   9504     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
   9505     unsigned int final_extra_data_size = 0;
   9506     struct v4l2_format fmt;
   9507     int ret = 0;
   9508     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   9509             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9510     bufreq.memory = V4L2_MEMORY_USERPTR;
   9511     bufreq.count = 1;
   9512     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9513         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9514         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9515         fmt.fmt.pix_mp.pixelformat = output_capability;
   9516     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9517         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9518         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9519         fmt.fmt.pix_mp.pixelformat = capture_capability;
   9520     } else {
   9521         eRet = OMX_ErrorBadParameter;
   9522     }
   9523     if (eRet==OMX_ErrorNone) {
   9524         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   9525     }
   9526     if (ret) {
   9527         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   9528         /*TODO: How to handle this case */
   9529         eRet = OMX_ErrorInsufficientResources;
   9530         return eRet;
   9531     } else {
   9532         buffer_prop->actualcount = bufreq.count;
   9533         buffer_prop->mincount = bufreq.count;
   9534         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
   9535     }
   9536     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   9537             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9538 
   9539     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   9540     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   9541 
   9542     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   9543 
   9544     update_resolution(fmt.fmt.pix_mp.width,
   9545             fmt.fmt.pix_mp.height,
   9546             fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
   9547             fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   9548     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   9549         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   9550     DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   9551 
   9552     if (ret) {
   9553         /*TODO: How to handle this case */
   9554         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   9555         eRet = OMX_ErrorInsufficientResources;
   9556     } else {
   9557         int extra_idx = 0;
   9558 
   9559         eRet = is_video_session_supported();
   9560         if (eRet)
   9561             return eRet;
   9562 
   9563         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   9564         buf_size = buffer_prop->buffer_size;
   9565         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   9566         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   9567             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   9568         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   9569             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   9570             return OMX_ErrorBadParameter;
   9571         }
   9572 
   9573         default_extra_data_size = VENUS_EXTRADATA_SIZE(
   9574                 drv_ctx.video_resolution.frame_height,
   9575                 drv_ctx.video_resolution.frame_width);
   9576         final_extra_data_size = extra_data_size > default_extra_data_size ?
   9577             extra_data_size : default_extra_data_size;
   9578 
   9579         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
   9580             (~(buffer_prop->alignment - 1));
   9581 
   9582         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
   9583         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   9584         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
   9585         if (!secure_mode)
   9586             buf_size += final_extra_data_size;
   9587         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   9588         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
   9589                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
   9590         if (extra_data_size)
   9591             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
   9592                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
   9593 
   9594         if (in_reconfig) // BufReq will be set to driver when port is disabled
   9595             buffer_prop->buffer_size = buf_size;
   9596         else if (buf_size != buffer_prop->buffer_size) {
   9597             buffer_prop->buffer_size = buf_size;
   9598             eRet = set_buffer_req(buffer_prop);
   9599         }
   9600     }
   9601     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
   9602             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9603     return eRet;
   9604 }
   9605 
   9606 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   9607 {
   9608     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9609     unsigned buf_size = 0;
   9610     struct v4l2_format fmt;
   9611     struct v4l2_requestbuffers bufreq;
   9612     int ret;
   9613     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
   9614             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9615     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   9616     if (buf_size != buffer_prop->buffer_size) {
   9617         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
   9618                 (unsigned int)buffer_prop->buffer_size, buf_size);
   9619         eRet = OMX_ErrorBadParameter;
   9620     } else {
   9621         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   9622         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   9623         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   9624         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   9625 
   9626         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9627             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9628             fmt.fmt.pix_mp.pixelformat = output_capability;
   9629         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9630             fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9631             fmt.fmt.pix_mp.pixelformat = capture_capability;
   9632         } else {
   9633             eRet = OMX_ErrorBadParameter;
   9634         }
   9635 
   9636         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   9637         if (ret) {
   9638             /*TODO: How to handle this case */
   9639             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   9640             eRet = OMX_ErrorInsufficientResources;
   9641         }
   9642 
   9643         bufreq.memory = V4L2_MEMORY_USERPTR;
   9644         bufreq.count = buffer_prop->actualcount;
   9645         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9646             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9647         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9648             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9649         } else {
   9650             eRet = OMX_ErrorBadParameter;
   9651         }
   9652 
   9653         if (eRet==OMX_ErrorNone) {
   9654             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   9655         }
   9656 
   9657         if (ret) {
   9658             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   9659             /*TODO: How to handle this case */
   9660             eRet = OMX_ErrorInsufficientResources;
   9661         } else if (bufreq.count < buffer_prop->actualcount) {
   9662             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   9663                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   9664                     buffer_prop->actualcount, bufreq.count);
   9665             eRet = OMX_ErrorInsufficientResources;
   9666         } else {
   9667             if (!client_buffers.update_buffer_req()) {
   9668                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   9669                 eRet = OMX_ErrorInsufficientResources;
   9670             }
   9671         }
   9672     }
   9673     return eRet;
   9674 }
   9675 
   9676 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   9677 {
   9678     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9679     return eRet;
   9680 }
   9681 
   9682 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   9683 {
   9684     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9685     struct v4l2_format fmt;
   9686     if (!portDefn) {
   9687         return OMX_ErrorBadParameter;
   9688     }
   9689     DEBUG_PRINT_LOW("omx_vdec::update_portdef");
   9690     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   9691     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   9692     portDefn->eDomain    = OMX_PortDomainVideo;
   9693     if (drv_ctx.frame_rate.fps_denominator > 0)
   9694         portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
   9695             drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
   9696     else {
   9697         DEBUG_PRINT_ERROR("Error: Divide by zero");
   9698         return OMX_ErrorBadParameter;
   9699     }
   9700     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   9701     if (0 == portDefn->nPortIndex) {
   9702         portDefn->eDir =  OMX_DirInput;
   9703         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   9704         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   9705         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   9706         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   9707         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   9708         portDefn->bEnabled   = m_inp_bEnabled;
   9709         portDefn->bPopulated = m_inp_bPopulated;
   9710 
   9711         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9712         fmt.fmt.pix_mp.pixelformat = output_capability;
   9713     } else if (1 == portDefn->nPortIndex) {
   9714         unsigned int buf_size = 0;
   9715         if (!client_buffers.update_buffer_req()) {
   9716             DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
   9717             return OMX_ErrorHardware;
   9718         }
   9719         if (!client_buffers.get_buffer_req(buf_size)) {
   9720             DEBUG_PRINT_ERROR("update buffer requirements");
   9721             return OMX_ErrorHardware;
   9722         }
   9723         portDefn->nBufferSize = buf_size;
   9724         portDefn->eDir =  OMX_DirOutput;
   9725         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   9726         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   9727         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   9728         portDefn->bEnabled   = m_out_bEnabled;
   9729         portDefn->bPopulated = m_out_bPopulated;
   9730         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   9731             DEBUG_PRINT_ERROR("Error in getting color format");
   9732             return OMX_ErrorHardware;
   9733         }
   9734         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9735         fmt.fmt.pix_mp.pixelformat = capture_capability;
   9736     } else {
   9737         portDefn->eDir = OMX_DirMax;
   9738         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   9739                 (int)portDefn->nPortIndex);
   9740         eRet = OMX_ErrorBadPortIndex;
   9741     }
   9742     if (is_down_scalar_enabled) {
   9743         int ret = 0;
   9744         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   9745         if (ret) {
   9746             DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
   9747             return OMX_ErrorHardware;
   9748         } else {
   9749             portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
   9750             portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
   9751             portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
   9752             portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
   9753         }
   9754     } else {
   9755         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   9756         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   9757         portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   9758         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   9759     }
   9760 
   9761     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
   9762        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
   9763            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
   9764            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
   9765     }
   9766     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
   9767             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
   9768             (unsigned int)portDefn->nPortIndex,
   9769             (unsigned int)portDefn->format.video.nFrameWidth,
   9770             (unsigned int)portDefn->format.video.nFrameHeight,
   9771             (int)portDefn->format.video.nStride,
   9772             (unsigned int)portDefn->format.video.nSliceHeight,
   9773             (unsigned int)portDefn->format.video.eColorFormat,
   9774             (unsigned int)portDefn->nBufferSize,
   9775             (unsigned int)portDefn->nBufferCountActual);
   9776 
   9777     return eRet;
   9778 }
   9779 
   9780 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   9781 {
   9782     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9783     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   9784     unsigned i= 0;
   9785 
   9786     if (!m_out_mem_ptr) {
   9787         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
   9788         int nBufHdrSize        = 0;
   9789         int nPlatformEntrySize = 0;
   9790         int nPlatformListSize  = 0;
   9791         int nPMEMInfoSize = 0;
   9792         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   9793         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   9794         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   9795 
   9796         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
   9797                 drv_ctx.op_buf.actualcount);
   9798         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   9799             sizeof(OMX_BUFFERHEADERTYPE);
   9800 
   9801         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   9802             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   9803         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   9804             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   9805         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   9806             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   9807 
   9808         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   9809                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   9810                 nPMEMInfoSize,
   9811                 nPlatformListSize);
   9812         DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
   9813                 m_out_bm_count);
   9814         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   9815         // Alloc mem for platform specific info
   9816         char *pPtr=NULL;
   9817         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   9818                 nPMEMInfoSize,1);
   9819         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   9820                        calloc (sizeof(struct vdec_bufferpayload),
   9821                                drv_ctx.op_buf.actualcount);
   9822         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   9823                      calloc (sizeof (struct vdec_output_frameinfo),
   9824                              drv_ctx.op_buf.actualcount);
   9825         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   9826             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
   9827             return OMX_ErrorInsufficientResources;
   9828         }
   9829 
   9830 #ifdef USE_ION
   9831         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   9832                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   9833         if (!drv_ctx.op_buf_ion_info) {
   9834             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   9835             return OMX_ErrorInsufficientResources;
   9836         }
   9837 #endif
   9838         if (dynamic_buf_mode) {
   9839             out_dynamic_list = (struct dynamic_buf_list *) \
   9840                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   9841             if (out_dynamic_list) {
   9842                for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++)
   9843                   out_dynamic_list[i].dup_fd = -1;
   9844             }
   9845         }
   9846 
   9847         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   9848                 && drv_ctx.ptr_respbuffer) {
   9849             bufHdr          =  m_out_mem_ptr;
   9850             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   9851             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   9852                 (((char *) m_platform_list)  + nPlatformListSize);
   9853             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   9854                 (((char *) m_platform_entry) + nPlatformEntrySize);
   9855             pPlatformList   = m_platform_list;
   9856             pPlatformEntry  = m_platform_entry;
   9857             pPMEMInfo       = m_pmem_info;
   9858 
   9859             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   9860 
   9861             // Settting the entire storage nicely
   9862             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
   9863                     m_out_mem_ptr,pPlatformEntry);
   9864             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   9865             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   9866                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   9867                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   9868                 // Set the values when we determine the right HxW param
   9869                 bufHdr->nAllocLen          = 0;
   9870                 bufHdr->nFilledLen         = 0;
   9871                 bufHdr->pAppPrivate        = NULL;
   9872                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   9873                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   9874                 pPlatformEntry->entry      = pPMEMInfo;
   9875                 // Initialize the Platform List
   9876                 pPlatformList->nEntries    = 1;
   9877                 pPlatformList->entryList   = pPlatformEntry;
   9878                 // Keep pBuffer NULL till vdec is opened
   9879                 bufHdr->pBuffer            = NULL;
   9880                 pPMEMInfo->offset          =  0;
   9881                 pPMEMInfo->pmem_fd = -1;
   9882                 bufHdr->pPlatformPrivate = pPlatformList;
   9883                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   9884 #ifdef USE_ION
   9885                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   9886 #endif
   9887                 /*Create a mapping between buffers*/
   9888                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   9889                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   9890                                     &drv_ctx.ptr_outputbuffer[i];
   9891                 // Move the buffer and buffer header pointers
   9892                 bufHdr++;
   9893                 pPMEMInfo++;
   9894                 pPlatformEntry++;
   9895                 pPlatformList++;
   9896             }
   9897         } else {
   9898             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   9899                     m_out_mem_ptr, pPtr);
   9900             if (m_out_mem_ptr) {
   9901                 free(m_out_mem_ptr);
   9902                 m_out_mem_ptr = NULL;
   9903             }
   9904             if (pPtr) {
   9905                 free(pPtr);
   9906                 pPtr = NULL;
   9907             }
   9908             if (drv_ctx.ptr_outputbuffer) {
   9909                 free(drv_ctx.ptr_outputbuffer);
   9910                 drv_ctx.ptr_outputbuffer = NULL;
   9911             }
   9912             if (drv_ctx.ptr_respbuffer) {
   9913                 free(drv_ctx.ptr_respbuffer);
   9914                 drv_ctx.ptr_respbuffer = NULL;
   9915             }
   9916 #ifdef USE_ION
   9917             if (drv_ctx.op_buf_ion_info) {
   9918                 DEBUG_PRINT_LOW("Free o/p ion context");
   9919                 free(drv_ctx.op_buf_ion_info);
   9920                 drv_ctx.op_buf_ion_info = NULL;
   9921             }
   9922 #endif
   9923             eRet =  OMX_ErrorInsufficientResources;
   9924         }
   9925     } else {
   9926         eRet =  OMX_ErrorInsufficientResources;
   9927     }
   9928     return eRet;
   9929 }
   9930 
   9931 void omx_vdec::complete_pending_buffer_done_cbs()
   9932 {
   9933     unsigned long p1, p2, ident;
   9934     omx_cmd_queue tmp_q, pending_bd_q;
   9935     pthread_mutex_lock(&m_lock);
   9936     // pop all pending GENERATE FDB from ftb queue
   9937     while (m_ftb_q.m_size) {
   9938         m_ftb_q.pop_entry(&p1,&p2,&ident);
   9939         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   9940             pending_bd_q.insert_entry(p1,p2,ident);
   9941         } else {
   9942             tmp_q.insert_entry(p1,p2,ident);
   9943         }
   9944     }
   9945     //return all non GENERATE FDB to ftb queue
   9946     while (tmp_q.m_size) {
   9947         tmp_q.pop_entry(&p1,&p2,&ident);
   9948         m_ftb_q.insert_entry(p1,p2,ident);
   9949     }
   9950     // pop all pending GENERATE EDB from etb queue
   9951     while (m_etb_q.m_size) {
   9952         m_etb_q.pop_entry(&p1,&p2,&ident);
   9953         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   9954             pending_bd_q.insert_entry(p1,p2,ident);
   9955         } else {
   9956             tmp_q.insert_entry(p1,p2,ident);
   9957         }
   9958     }
   9959     //return all non GENERATE FDB to etb queue
   9960     while (tmp_q.m_size) {
   9961         tmp_q.pop_entry(&p1,&p2,&ident);
   9962         m_etb_q.insert_entry(p1,p2,ident);
   9963     }
   9964     pthread_mutex_unlock(&m_lock);
   9965     // process all pending buffer dones
   9966     while (pending_bd_q.m_size) {
   9967         pending_bd_q.pop_entry(&p1,&p2,&ident);
   9968         switch (ident) {
   9969             case OMX_COMPONENT_GENERATE_EBD:
   9970                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   9971                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   9972                     omx_report_error ();
   9973                 }
   9974                 break;
   9975 
   9976             case OMX_COMPONENT_GENERATE_FBD:
   9977                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   9978                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   9979                     omx_report_error ();
   9980                 }
   9981                 break;
   9982         }
   9983     }
   9984 }
   9985 
   9986 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   9987 {
   9988     OMX_U32 new_frame_interval = 0;
   9989     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   9990             && llabs(act_timestamp - prev_ts) > 2000) {
   9991         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
   9992             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
   9993         if (new_frame_interval != frm_int || frm_int == 0) {
   9994             frm_int = new_frame_interval;
   9995             if (frm_int) {
   9996                 drv_ctx.frame_rate.fps_numerator = 1e6;
   9997                 drv_ctx.frame_rate.fps_denominator = frm_int;
   9998                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
   9999                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   10000                         (float)drv_ctx.frame_rate.fps_denominator);
   10001                 m_perf_control.request_cores(frm_int);
   10002                 /* We need to report the difference between this FBD and the previous FBD
   10003                  * back to the driver for clock scaling purposes. */
   10004                 struct v4l2_outputparm oparm;
   10005                 /*XXX: we're providing timing info as seconds per frame rather than frames
   10006                  * per second.*/
   10007                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   10008                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   10009 
   10010                 struct v4l2_streamparm sparm;
   10011                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10012                 sparm.parm.output = oparm;
   10013                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   10014                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   10015                             performance might be affected");
   10016                 }
   10017 
   10018             }
   10019         }
   10020     }
   10021     prev_ts = act_timestamp;
   10022 }
   10023 
   10024 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   10025 {
   10026     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   10027         prev_ts = act_timestamp;
   10028         prev_ts_actual = act_timestamp;
   10029         rst_prev_ts = false;
   10030     } else if (VALID_TS(prev_ts)) {
   10031         bool codec_cond = (drv_ctx.timestamp_adjust)?
   10032             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
   10033             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
   10034              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
   10035         if (frm_int > 0 && codec_cond) {
   10036             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   10037             act_timestamp = prev_ts + frm_int;
   10038             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   10039             prev_ts = act_timestamp;
   10040         } else {
   10041             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
   10042                 // ensure that timestamps can never step backwards when in display order
   10043                 act_timestamp = prev_ts;
   10044             }
   10045             set_frame_rate(act_timestamp);
   10046         }
   10047     } else if (frm_int > 0)          // In this case the frame rate was set along
   10048     {                               // with the port definition, start ts with 0
   10049         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   10050         rst_prev_ts = true;
   10051     }
   10052 }
   10053 
   10054 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
   10055     OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects)
   10056 {
   10057     switch (primaries) {
   10058         case MSM_VIDC_BT709_5:
   10059             *color_space = ITU_R_709;
   10060             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
   10061             break;
   10062         case MSM_VIDC_BT470_6_M:
   10063             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
   10064             break;
   10065         case MSM_VIDC_BT601_6_625:
   10066             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10067             break;
   10068         case MSM_VIDC_BT601_6_525:
   10069             *color_space = range ? ITU_R_601_FR : ITU_R_601;
   10070             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   10071             break;
   10072         case MSM_VIDC_GENERIC_FILM:
   10073             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
   10074             break;
   10075         case MSM_VIDC_BT2020:
   10076             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   10077             break;
   10078         case MSM_VIDC_UNSPECIFIED:
   10079             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
   10080         default:
   10081             //aspects->mPrimaries = ColorAspects::PrimariesOther;
   10082             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10083             break;
   10084     }
   10085 
   10086     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
   10087 
   10088     switch (transfer) {
   10089         case MSM_VIDC_TRANSFER_BT709_5:
   10090         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
   10091             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10092             break;
   10093         case MSM_VIDC_TRANSFER_BT_470_6_M:
   10094             aspects->mTransfer = ColorAspects::TransferGamma22;
   10095             break;
   10096         case MSM_VIDC_TRANSFER_BT_470_6_BG:
   10097             aspects->mTransfer = ColorAspects::TransferGamma28;
   10098             break;
   10099         case MSM_VIDC_TRANSFER_SMPTE_240M:
   10100             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   10101             break;
   10102         case MSM_VIDC_TRANSFER_LINEAR:
   10103             aspects->mTransfer = ColorAspects::TransferLinear;
   10104             break;
   10105         case MSM_VIDC_TRANSFER_IEC_61966:
   10106             aspects->mTransfer = ColorAspects::TransferXvYCC;
   10107             break;
   10108         case MSM_VIDC_TRANSFER_BT_1361:
   10109             aspects->mTransfer = ColorAspects::TransferBT1361;
   10110             break;
   10111         case MSM_VIDC_TRANSFER_SRGB:
   10112             aspects->mTransfer = ColorAspects::TransferSRGB;
   10113             break;
   10114         default:
   10115             //aspects->mTransfer = ColorAspects::TransferOther;
   10116             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
   10117             break;
   10118     }
   10119 
   10120     switch (matrix) {
   10121         case MSM_VIDC_MATRIX_BT_709_5:
   10122             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10123             break;
   10124         case MSM_VIDC_MATRIX_FCC_47:
   10125             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
   10126             break;
   10127         case MSM_VIDC_MATRIX_601_6_625:
   10128         case MSM_VIDC_MATRIX_601_6_525:
   10129             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   10130             break;
   10131         case MSM_VIDC_MATRIX_SMPTE_240M:
   10132             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
   10133             break;
   10134         case MSM_VIDC_MATRIX_BT_2020:
   10135             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   10136             break;
   10137         case MSM_VIDC_MATRIX_BT_2020_CONST:
   10138             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
   10139             break;
   10140         default:
   10141             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   10142             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   10143             break;
   10144     }
   10145 }
   10146 
   10147 void omx_vdec::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
   10148         DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
   10149                 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
   10150 }
   10151 
   10152 void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index)
   10153 {
   10154     ColorSpace_t color_space = ITU_R_601;
   10155     ColorAspects tempAspects;
   10156     memset(&tempAspects, 0x0, sizeof(ColorAspects));
   10157     ColorAspects *aspects = &tempAspects;
   10158 
   10159     switch(output_capability) {
   10160         case V4L2_PIX_FMT_MPEG2:
   10161             {
   10162                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   10163                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
   10164 
   10165                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
   10166                  * understand this code */
   10167 
   10168                 if (seqdisp_payload && seqdisp_payload->color_descp) {
   10169 
   10170                     convert_color_space_info(seqdisp_payload->color_primaries, 1,
   10171                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   10172                             &color_space,aspects);
   10173                     m_disp_hor_size = seqdisp_payload->disp_width;
   10174                     m_disp_vert_size = seqdisp_payload->disp_height;
   10175                 }
   10176             }
   10177             break;
   10178         case V4L2_PIX_FMT_H264:
   10179         case V4L2_PIX_FMT_HEVC:
   10180             {
   10181                 struct msm_vidc_vui_display_info_payload *display_info_payload;
   10182                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
   10183 
   10184                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
   10185 
   10186                 if (display_info_payload->video_signal_present_flag &&
   10187                         display_info_payload->color_description_present_flag) {
   10188                     convert_color_space_info(display_info_payload->color_primaries,
   10189                             display_info_payload->video_full_range_flag,
   10190                             display_info_payload->transfer_characteristics,
   10191                             display_info_payload->matrix_coefficients,
   10192                             &color_space,aspects);
   10193                 }
   10194             }
   10195             break;
   10196         case V4L2_PIX_FMT_VC1_ANNEX_G:
   10197         case V4L2_PIX_FMT_VC1_ANNEX_L:
   10198             {
   10199                 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload;
   10200                 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data;
   10201 
   10202                 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23
   10203                  * SMPTE 421M to understand this code */
   10204 
   10205                 if (m_enable_android_native_buffers &&
   10206                         vc1_seq_disp_payload->color_primaries) {
   10207 
   10208                     convert_color_space_info(vc1_seq_disp_payload->color_primaries,
   10209                             1,
   10210                             vc1_seq_disp_payload->transfer_char,
   10211                             vc1_seq_disp_payload->matrix_coeffs,
   10212                             &color_space,aspects);
   10213                 }
   10214             }
   10215             break;
   10216         case V4L2_PIX_FMT_VP8:
   10217             {
   10218                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   10219                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   10220 
   10221                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
   10222                  * to understand this code */
   10223 
   10224                 if (vpx_color_space_payload->color_space == 0) {
   10225                     color_space = ITU_R_601;
   10226                 } else {
   10227                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
   10228                     break;
   10229                 }
   10230             }
   10231             break;
   10232         case V4L2_PIX_FMT_VP9:
   10233             {
   10234                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   10235                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   10236 
   10237                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
   10238                  * to understand this code */
   10239 
   10240                 switch(vpx_color_space_payload->color_space) {
   10241                     case MSM_VIDC_CS_BT_601:
   10242                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   10243                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10244                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10245                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10246                         break;
   10247                     case MSM_VIDC_CS_BT_709:
   10248                         color_space = ITU_R_709;
   10249                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10250                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10251                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
   10252                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10253                         break;
   10254                     case MSM_VIDC_CS_SMPTE_170:
   10255                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10256                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10257                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10258                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10259                         break;
   10260                     case MSM_VIDC_CS_SMPTE_240:
   10261                         aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   10262                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   10263                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10264                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10265                         break;
   10266                     case MSM_VIDC_CS_BT_2020:
   10267                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   10268                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
   10269                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   10270                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10271                         break;
   10272                     case MSM_VIDC_CS_RESERVED:
   10273                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   10274                         aspects->mTransfer = ColorAspects::TransferOther;
   10275                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   10276                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10277                         break;
   10278                     case MSM_VIDC_CS_RGB:
   10279                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10280                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10281                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   10282                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10283                         break;
   10284                     default:
   10285                         break;
   10286                 }
   10287             }
   10288             break;
   10289         default:
   10290             break;
   10291     }
   10292     if (m_enable_android_native_buffers) {
   10293         DEBUG_PRINT_HIGH("setMetaData for Color Space = 0x%x (601=%u FR=%u 709=%u)", color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   10294         set_colorspace_in_handle(color_space, buf_index);
   10295     }
   10296     print_debug_color_aspects(aspects, "Bitstream");
   10297 
   10298     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
   10299             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
   10300             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
   10301             m_internal_color_space.sAspects.mRange != aspects->mRange) {
   10302         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
   10303         m_internal_color_space.bDataSpaceChanged = OMX_TRUE;
   10304 
   10305         DEBUG_PRINT_HIGH("Initiating PORT Reconfig");
   10306         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
   10307         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
   10308 
   10309         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   10310                 OMX_QTIIndexConfigDescribeColorAspects,
   10311                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   10312     }
   10313 }
   10314 
   10315 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
   10316     private_handle_t *private_handle = NULL;
   10317     if (buf_index < drv_ctx.op_buf.actualcount &&
   10318             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   10319             native_buffer[buf_index].privatehandle) {
   10320         private_handle = native_buffer[buf_index].privatehandle;
   10321     }
   10322     if (private_handle) {
   10323         setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
   10324     }
   10325 }
   10326 
   10327 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   10328 {
   10329     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
   10330     OMX_U32 num_conceal_MB = 0;
   10331     OMX_TICKS time_stamp = 0;
   10332     OMX_U32 frame_rate = 0;
   10333     unsigned long consumed_len = 0;
   10334     OMX_U32 num_MB_in_frame;
   10335     OMX_U32 recovery_sei_flags = 1;
   10336     int enable = 0;
   10337 
   10338     int buf_index = p_buf_hdr - m_out_mem_ptr;
   10339     if (buf_index >= drv_ctx.extradata_info.count) {
   10340         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   10341                 buf_index, drv_ctx.extradata_info.count);
   10342         return;
   10343     }
   10344     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   10345 
   10346     if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) {
   10347         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
   10348         return;
   10349     }
   10350 
   10351     OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
   10352         p_buf_hdr->nOffset;
   10353 
   10354     if (!drv_ctx.extradata_info.uaddr) {
   10355         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
   10356         return;
   10357     }
   10358     if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
   10359         DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
   10360         p_extra = NULL;
   10361         return;
   10362     }
   10363     if (!secure_mode)
   10364         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   10365             ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   10366     else
   10367         p_extra = m_other_extradata;
   10368     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   10369 
   10370     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   10371         p_extra = NULL;
   10372         DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   10373         return;
   10374     }
   10375     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   10376     if (data && p_extra) {
   10377         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   10378                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
   10379             if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
   10380                 DEBUG_PRINT_LOW("Invalid extra data size");
   10381                 break;
   10382             }
   10383 
   10384             if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   10385                 p_extra = NULL;
   10386                 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   10387                 return;
   10388             }
   10389 
   10390             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
   10391             switch ((unsigned long)data->eType) {
   10392                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
   10393                     struct msm_vidc_interlace_payload *payload;
   10394                     OMX_U32 interlace_color_format;
   10395                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
   10396                     if (payload) {
   10397                         enable = 1;
   10398                         switch (payload->format) {
   10399                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
   10400                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   10401                                 enable = 0;
   10402                                 break;
   10403                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
   10404                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   10405                                 break;
   10406                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
   10407                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   10408                                 break;
   10409                             default:
   10410                                 DEBUG_PRINT_LOW("default case - set interlace to topfield");
   10411                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   10412                         }
   10413                         switch (payload->color_format) {
   10414                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12:
   10415                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10416                                drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   10417                                break;
   10418                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC:
   10419                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   10420                                drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   10421                                break;
   10422                            default:
   10423                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10424                                DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame");
   10425                         }
   10426                     }
   10427 
   10428                     if (m_enable_android_native_buffers) {
   10429                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d",
   10430                                          payload->format, interlace_color_format ,enable,
   10431                                         (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
   10432 
   10433                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   10434                                PP_PARAM_INTERLACED, (void*)&enable);
   10435 
   10436                         if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   10437                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   10438                                LINEAR_FORMAT, (void*)&interlace_color_format);
   10439                         }
   10440                     }
   10441                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   10442                         append_interlace_extradata(p_extra, payload->format,
   10443                                       p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
   10444                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10445                     }
   10446                     break;
   10447                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
   10448                     struct msm_vidc_framerate_payload *frame_rate_payload;
   10449                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
   10450                     frame_rate = frame_rate_payload->frame_rate;
   10451                     break;
   10452                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
   10453                     struct msm_vidc_ts_payload *time_stamp_payload;
   10454                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
   10455                     time_stamp = time_stamp_payload->timestamp_lo;
   10456                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   10457                     p_buf_hdr->nTimeStamp = time_stamp;
   10458                     break;
   10459                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
   10460                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   10461                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
   10462                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   10463                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   10464                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   10465                     break;
   10466                 case MSM_VIDC_EXTRADATA_INDEX:
   10467                     int *etype;
   10468                     etype  = (int *)(void *)data->data;
   10469                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
   10470                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   10471                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   10472                         if (aspect_ratio_payload) {
   10473                             ((struct vdec_output_frameinfo *)
   10474                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   10475                             ((struct vdec_output_frameinfo *)
   10476                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   10477                         }
   10478                     }
   10479                     break;
   10480                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
   10481                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   10482                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
   10483                     recovery_sei_flags = recovery_sei_payload->flags;
   10484                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
   10485                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   10486                         DEBUG_PRINT_HIGH("***************************************************");
   10487                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   10488                         DEBUG_PRINT_HIGH("***************************************************");
   10489                     }
   10490                     break;
   10491                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
   10492                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
   10493                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
   10494                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
   10495                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
   10496                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
   10497                         return;
   10498                     }
   10499                     break;
   10500                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
   10501                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
   10502                 case MSM_VIDC_EXTRADATA_VC1_SEQDISP:
   10503                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
   10504                         handle_color_space_info((void *)data->data, buf_index);
   10505                     break;
   10506                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
   10507                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
   10508                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
   10509                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
   10510                         append_framepack_extradata(p_extra, s3d_frame_packing_payload);
   10511                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10512                     }
   10513                     break;
   10514                 case MSM_VIDC_EXTRADATA_FRAME_QP:
   10515                     struct msm_vidc_frame_qp_payload *qp_payload;
   10516                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
   10517                     if (client_extradata & OMX_QP_EXTRADATA) {
   10518                         append_qp_extradata(p_extra, qp_payload);
   10519                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10520                     }
   10521                     break;
   10522                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
   10523                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
   10524                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
   10525                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
   10526                         append_bitsinfo_extradata(p_extra, bits_info_payload);
   10527                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10528                     }
   10529                     break;
   10530                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
   10531                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
   10532                         append_user_extradata(p_extra, data);
   10533                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10534                     }
   10535                     break;
   10536                 case MSM_VIDC_EXTRADATA_VQZIP_SEI:
   10537                     struct msm_vidc_vqzip_sei_payload *vqzip_payload;
   10538                     vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data;
   10539                     if (client_extradata & OMX_VQZIPSEI_EXTRADATA) {
   10540                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10541                         append_vqzip_extradata(p_extra, vqzip_payload);
   10542                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10543                     }
   10544                     break;
   10545                 default:
   10546                     DEBUG_PRINT_LOW("Unrecognized extradata");
   10547                     goto unrecognized_extradata;
   10548             }
   10549             consumed_len += data->nSize;
   10550             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   10551         }
   10552         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   10553             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10554             append_frame_info_extradata(p_extra,
   10555                     num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   10556                     time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   10557                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   10558             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10559         }
   10560         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
   10561             append_frame_dimension_extradata(p_extra);
   10562             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10563         }
   10564     }
   10565 unrecognized_extradata:
   10566     if (client_extradata && p_extra) {
   10567         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10568         append_terminator_extradata(p_extra);
   10569     }
   10570     if (secure_mode && p_extradata && m_other_extradata) {
   10571         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
   10572         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
   10573         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
   10574         ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
   10575         ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
   10576     }
   10577     return;
   10578 }
   10579 
   10580 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
   10581         bool is_internal, bool enable)
   10582 {
   10583     OMX_ERRORTYPE ret = OMX_ErrorNone;
   10584     struct v4l2_control control;
   10585     if (m_state != OMX_StateLoaded) {
   10586         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   10587         return OMX_ErrorIncorrectStateOperation;
   10588     }
   10589     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
   10590             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
   10591 
   10592     if (!is_internal) {
   10593         if (enable)
   10594             client_extradata |= requested_extradata;
   10595         else
   10596             client_extradata = client_extradata & ~requested_extradata;
   10597     }
   10598 
   10599     if (enable) {
   10600         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   10601             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10602             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   10603             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10604                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   10605                         " Quality of interlaced clips might be impacted.");
   10606             }
   10607         }
   10608         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   10609             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10610             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   10611             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10612                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
   10613             }
   10614             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10615             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   10616             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10617                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
   10618             }
   10619             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10620             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   10621             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10622                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
   10623             }
   10624             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10625             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   10626             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10627                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10628             }
   10629             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10630             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
   10631             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10632                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10633             }
   10634             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   10635                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10636                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   10637                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10638                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10639                 }
   10640             }
   10641         }
   10642         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   10643             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10644             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   10645             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10646                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
   10647             }
   10648         }
   10649         if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
   10650             if (output_capability == V4L2_PIX_FMT_H264) {
   10651                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
   10652                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10653                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
   10654                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10655                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
   10656                 }
   10657             } else {
   10658                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
   10659             }
   10660         }
   10661         if (requested_extradata & OMX_QP_EXTRADATA) {
   10662             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10663             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   10664             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10665                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   10666             }
   10667         }
   10668         if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
   10669             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10670             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
   10671             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10672                 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
   10673             }
   10674         }
   10675         if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
   10676             if (secure_mode) {
   10677                 DEBUG_PRINT_HIGH("ExtnUser Extra Data not supported for secure sessions");
   10678                 return OMX_ErrorUnsupportedSetting;
   10679             }
   10680             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10681             control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
   10682             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10683                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
   10684             }
   10685         }
   10686         if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) {
   10687             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10688             control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI;
   10689             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10690                 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata");
   10691             }
   10692             client_extradata |= OMX_VQZIPSEI_EXTRADATA;
   10693 
   10694             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10695             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   10696             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10697                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   10698             }
   10699             client_extradata |= OMX_QP_EXTRADATA;
   10700         }
   10701         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
   10702             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10703             switch(output_capability) {
   10704                 case V4L2_PIX_FMT_H264:
   10705                 case V4L2_PIX_FMT_HEVC:
   10706                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
   10707                     break;
   10708                 case CODEC_TYPE_MPEG2:
   10709                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   10710                     break;
   10711                 case V4L2_PIX_FMT_VP8:
   10712                 case V4L2_PIX_FMT_VP9:
   10713                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
   10714                     break;
   10715                 case V4L2_PIX_FMT_VC1_ANNEX_G:
   10716                 case V4L2_PIX_FMT_VC1_ANNEX_L:
   10717                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP;
   10718                     break;
   10719                 default:
   10720                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
   10721                     return ret;
   10722             }
   10723 
   10724             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10725                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
   10726             }
   10727         }
   10728     }
   10729     ret = get_buffer_req(&drv_ctx.op_buf);
   10730     return ret;
   10731 }
   10732 
   10733 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   10734 {
   10735     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   10736     OMX_U8 *data_ptr = extra->data, data = 0;
   10737     while (byte_count < extra->nDataSize) {
   10738         data = *data_ptr;
   10739         while (data) {
   10740             num_MB += (data&0x01);
   10741             data >>= 1;
   10742         }
   10743         data_ptr++;
   10744         byte_count++;
   10745     }
   10746     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   10747             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   10748     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   10749 }
   10750 
   10751 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   10752 {
   10753     if (!m_debug_extradata || !extra)
   10754         return;
   10755 
   10756 
   10757     DEBUG_PRINT_HIGH(
   10758             "============== Extra Data ==============\n"
   10759             "           Size: %u\n"
   10760             "        Version: %u\n"
   10761             "      PortIndex: %u\n"
   10762             "           Type: %x\n"
   10763             "       DataSize: %u",
   10764             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
   10765             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
   10766 
   10767     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   10768         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   10769         DEBUG_PRINT_HIGH(
   10770                 "------ Interlace Format ------\n"
   10771                 "                Size: %u\n"
   10772                 "             Version: %u\n"
   10773                 "           PortIndex: %u\n"
   10774                 " Is Interlace Format: %d\n"
   10775                 "   Interlace Formats: %u\n"
   10776                 "=========== End of Interlace ===========",
   10777                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
   10778                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
   10779     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   10780         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   10781 
   10782         DEBUG_PRINT_HIGH(
   10783                 "-------- Frame Format --------\n"
   10784                 "             Picture Type: %d\n"
   10785                 "           Interlace Type: %d\n"
   10786                 " Pan Scan Total Frame Num: %u\n"
   10787                 "   Concealed Macro Blocks: %u\n"
   10788                 "               frame rate: %u\n"
   10789                 "               Time Stamp: %llu\n"
   10790                 "           Aspect Ratio X: %u\n"
   10791                 "           Aspect Ratio Y: %u",
   10792                 fminfo->ePicType,
   10793                 fminfo->interlaceType,
   10794                 (unsigned int)fminfo->panScan.numWindows,
   10795                 (unsigned int)fminfo->nConcealedMacroblocks,
   10796                 (unsigned int)fminfo->nFrameRate,
   10797                 fminfo->nTimeStamp,
   10798                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
   10799                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
   10800 
   10801         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   10802             DEBUG_PRINT_HIGH(
   10803                     "------------------------------"
   10804                     "     Pan Scan Frame Num: %u\n"
   10805                     "            Rectangle x: %d\n"
   10806                     "            Rectangle y: %d\n"
   10807                     "           Rectangle dx: %d\n"
   10808                     "           Rectangle dy: %d",
   10809                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
   10810                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
   10811         }
   10812 
   10813         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   10814     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
   10815         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   10816         DEBUG_PRINT_HIGH(
   10817                 "------------------ Framepack Format ----------\n"
   10818                 "                           id: %u \n"
   10819                 "                  cancel_flag: %u \n"
   10820                 "                         type: %u \n"
   10821                 " quincunx_sampling_flagFormat: %u \n"
   10822                 "  content_interpretation_type: %u \n"
   10823                 "        spatial_flipping_flag: %u \n"
   10824                 "          frame0_flipped_flag: %u \n"
   10825                 "             field_views_flag: %u \n"
   10826                 " current_frame_is_frame0_flag: %u \n"
   10827                 "   frame0_self_contained_flag: %u \n"
   10828                 "   frame1_self_contained_flag: %u \n"
   10829                 "       frame0_grid_position_x: %u \n"
   10830                 "       frame0_grid_position_y: %u \n"
   10831                 "       frame1_grid_position_x: %u \n"
   10832                 "       frame1_grid_position_y: %u \n"
   10833                 "                reserved_byte: %u \n"
   10834                 "            repetition_period: %u \n"
   10835                 "               extension_flag: %u \n"
   10836                 "================== End of Framepack ===========",
   10837                 (unsigned int)framepack->id,
   10838                 (unsigned int)framepack->cancel_flag,
   10839                 (unsigned int)framepack->type,
   10840                 (unsigned int)framepack->quincunx_sampling_flag,
   10841                 (unsigned int)framepack->content_interpretation_type,
   10842                 (unsigned int)framepack->spatial_flipping_flag,
   10843                 (unsigned int)framepack->frame0_flipped_flag,
   10844                 (unsigned int)framepack->field_views_flag,
   10845                 (unsigned int)framepack->current_frame_is_frame0_flag,
   10846                 (unsigned int)framepack->frame0_self_contained_flag,
   10847                 (unsigned int)framepack->frame1_self_contained_flag,
   10848                 (unsigned int)framepack->frame0_grid_position_x,
   10849                 (unsigned int)framepack->frame0_grid_position_y,
   10850                 (unsigned int)framepack->frame1_grid_position_x,
   10851                 (unsigned int)framepack->frame1_grid_position_y,
   10852                 (unsigned int)framepack->reserved_byte,
   10853                 (unsigned int)framepack->repetition_period,
   10854                 (unsigned int)framepack->extension_flag);
   10855     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
   10856         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   10857         DEBUG_PRINT_HIGH(
   10858                 "---- QP (Frame quantization parameter) ----\n"
   10859                 "    Frame QP: %u \n"
   10860                 "================ End of QP ================\n",
   10861                 (unsigned int)qp->nQP);
   10862     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
   10863         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
   10864         DEBUG_PRINT_HIGH(
   10865                 "--------- Input bits information --------\n"
   10866                 "    Header bits: %u \n"
   10867                 "     Frame bits: %u \n"
   10868                 "===== End of Input bits information =====\n",
   10869                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
   10870     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
   10871         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
   10872         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
   10873         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
   10874         OMX_U32 i = 0;
   10875         DEBUG_PRINT_HIGH(
   10876                 "--------------  Userdata  -------------\n"
   10877                 "    Stream userdata type: %u\n"
   10878                 "          userdata size: %u\n"
   10879                 "    STREAM_USERDATA:",
   10880                 (unsigned int)userdata->type, (unsigned int)userdata_size);
   10881                 for (i = 0; i < userdata_size; i+=4) {
   10882                     DEBUG_PRINT_HIGH("        %x %x %x %x",
   10883                         data_ptr[i], data_ptr[i+1],
   10884                         data_ptr[i+2], data_ptr[i+3]);
   10885                 }
   10886         DEBUG_PRINT_HIGH(
   10887                 "=========== End of Userdata ===========");
   10888     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
   10889         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   10890         DEBUG_PRINT_HIGH(
   10891                 "--------------  VQZip  -------------\n"
   10892                 "    Size: %u\n",
   10893                 (unsigned int)vq->nSize);
   10894         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
   10895     } else if (extra->eType == OMX_ExtraDataNone) {
   10896         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   10897     } else {
   10898         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   10899     }
   10900 }
   10901 
   10902 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   10903         OMX_U32 interlaced_format_type, bool is_mbaff)
   10904 {
   10905     OMX_STREAMINTERLACEFORMAT *interlace_format;
   10906 
   10907     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   10908         return;
   10909     }
   10910     if (!extra) {
   10911        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
   10912        return;
   10913     }
   10914     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   10915     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   10916     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   10917     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   10918     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   10919     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   10920     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   10921     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   10922     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   10923 
   10924     if ((interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
   10925         interlace_format->bInterlaceFormat = OMX_FALSE;
   10926         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   10927         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   10928     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
   10929         interlace_format->bInterlaceFormat = OMX_TRUE;
   10930         interlace_format->nInterlaceFormats =  OMX_InterlaceInterleaveFrameTopFieldFirst;
   10931         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   10932     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
   10933         interlace_format->bInterlaceFormat = OMX_TRUE;
   10934         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   10935         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   10936     } else {
   10937         interlace_format->bInterlaceFormat = OMX_TRUE;
   10938         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   10939         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   10940     }
   10941     print_debug_extradata(extra);
   10942 }
   10943 
   10944 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   10945 {
   10946     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
   10947     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
   10948         return;
   10949     }
   10950     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
   10951     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   10952     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   10953     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
   10954     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
   10955     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
   10956     frame_dimension->nDecWidth = rectangle.nLeft;
   10957     frame_dimension->nDecHeight = rectangle.nTop;
   10958     frame_dimension->nActualWidth = rectangle.nWidth;
   10959     frame_dimension->nActualHeight = rectangle.nHeight;
   10960 }
   10961 
   10962 void omx_vdec::fill_aspect_ratio_info(
   10963         struct vdec_aspectratioinfo *aspect_ratio_info,
   10964         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   10965 {
   10966     m_extradata = frame_info;
   10967     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   10968     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   10969     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
   10970             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
   10971 }
   10972 
   10973 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   10974         OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
   10975         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
   10976         struct vdec_aspectratioinfo *aspect_ratio_info)
   10977 {
   10978     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   10979     struct msm_vidc_panscan_window *panscan_window;
   10980     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   10981         return;
   10982     }
   10983     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   10984     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   10985     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   10986     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   10987     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   10988     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   10989     switch (picture_type) {
   10990         case PICTURE_TYPE_I:
   10991             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   10992             break;
   10993         case PICTURE_TYPE_P:
   10994             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   10995             break;
   10996         case PICTURE_TYPE_B:
   10997             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   10998             break;
   10999         default:
   11000             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   11001     }
   11002     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   11003         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   11004     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   11005         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   11006     else
   11007         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   11008     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   11009     frame_info->nConcealedMacroblocks = num_conceal_mb;
   11010     frame_info->nFrameRate = frame_rate;
   11011     frame_info->nTimeStamp = time_stamp;
   11012     frame_info->panScan.numWindows = 0;
   11013     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   11014         if (m_disp_hor_size && m_disp_vert_size) {
   11015             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   11016             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   11017         } else {
   11018             frame_info->displayAspectRatio.displayHorizontalSize = 0;
   11019             frame_info->displayAspectRatio.displayVerticalSize = 0;
   11020         }
   11021     }
   11022 
   11023     if (panscan_payload) {
   11024         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   11025         panscan_window = &panscan_payload->wnd[0];
   11026         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   11027             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   11028             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   11029             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   11030             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   11031             panscan_window++;
   11032         }
   11033     }
   11034     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   11035     print_debug_extradata(extra);
   11036 }
   11037 
   11038 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11039 {
   11040     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   11041     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   11042     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11043     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11044     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   11045     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   11046     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
   11047     *portDefn = m_port_def;
   11048     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
   11049             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
   11050             (unsigned int)portDefn->format.video.nFrameWidth,
   11051             (unsigned int)portDefn->format.video.nStride,
   11052             (unsigned int)portDefn->format.video.nSliceHeight);
   11053 }
   11054 
   11055 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11056         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
   11057 {
   11058     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
   11059     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
   11060         DEBUG_PRINT_ERROR("frame packing size mismatch");
   11061         return;
   11062     }
   11063     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
   11064     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11065     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11066     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
   11067     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   11068     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   11069     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   11070     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
   11071     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11072     memcpy(&framepack->id, s3d_frame_packing_payload,
   11073         sizeof(struct msm_vidc_s3d_frame_packing_payload));
   11074     memcpy(&m_frame_pack_arrangement, framepack,
   11075         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   11076     print_debug_extradata(extra);
   11077 }
   11078 
   11079 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11080             struct msm_vidc_frame_qp_payload *qp_payload)
   11081 {
   11082     OMX_QCOM_EXTRADATA_QP * qp = NULL;
   11083     if (!qp_payload) {
   11084         DEBUG_PRINT_ERROR("QP payload is NULL");
   11085         return;
   11086     }
   11087     extra->nSize = OMX_QP_EXTRADATA_SIZE;
   11088     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11089     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11090     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
   11091     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
   11092     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   11093     qp->nQP = qp_payload->frame_qp;
   11094     print_debug_extradata(extra);
   11095 }
   11096 
   11097 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11098             struct msm_vidc_frame_bits_info_payload *bits_payload)
   11099 {
   11100     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
   11101     if (!bits_payload) {
   11102         DEBUG_PRINT_ERROR("bits info payload is NULL");
   11103         return;
   11104     }
   11105     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
   11106     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11107     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11108     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
   11109     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
   11110     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
   11111     bits->frame_bits = bits_payload->frame_bits;
   11112     bits->header_bits = bits_payload->header_bits;
   11113     print_debug_extradata(extra);
   11114 }
   11115 
   11116 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11117             OMX_OTHER_EXTRADATATYPE *p_user)
   11118 {
   11119     int userdata_size = 0;
   11120     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
   11121     userdata_payload =
   11122         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
   11123     userdata_size = p_user->nDataSize;
   11124     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
   11125     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11126     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11127     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
   11128     extra->nDataSize = userdata_size;
   11129     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
   11130         memcpy(extra->data, p_user->data, extra->nDataSize);
   11131     print_debug_extradata(extra);
   11132 }
   11133 
   11134 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11135 {
   11136     if (!client_extradata) {
   11137         return;
   11138     }
   11139     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   11140     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11141     extra->eType = OMX_ExtraDataNone;
   11142     extra->nDataSize = 0;
   11143     extra->data[0] = 0;
   11144 
   11145     print_debug_extradata(extra);
   11146 }
   11147 
   11148 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11149         struct msm_vidc_vqzip_sei_payload *vqzip_payload)
   11150 {
   11151     OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL;
   11152 
   11153     extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size;
   11154     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11155     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11156     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI;
   11157     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size;
   11158 
   11159     vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   11160     vq->nSize = vqzip_payload->size;
   11161     memcpy(vq->data, vqzip_payload->data, vqzip_payload->size);
   11162 
   11163     print_debug_extradata(extra);
   11164 }
   11165 
   11166 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   11167 {
   11168     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   11169     if (index >= drv_ctx.ip_buf.actualcount) {
   11170         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
   11171         return OMX_ErrorInsufficientResources;
   11172     }
   11173     if (m_desc_buffer_ptr == NULL) {
   11174         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   11175                     calloc( (sizeof(desc_buffer_hdr)),
   11176                             drv_ctx.ip_buf.actualcount);
   11177         if (m_desc_buffer_ptr == NULL) {
   11178             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
   11179             return OMX_ErrorInsufficientResources;
   11180         }
   11181     }
   11182 
   11183     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   11184     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   11185         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
   11186         return OMX_ErrorInsufficientResources;
   11187     }
   11188 
   11189     return eRet;
   11190 }
   11191 
   11192 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   11193 {
   11194     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
   11195     if (m_demux_entries < 8192) {
   11196         m_demux_offsets[m_demux_entries++] = address_offset;
   11197     }
   11198     return;
   11199 }
   11200 
   11201 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   11202 {
   11203     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   11204     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   11205     OMX_U32 index = 0;
   11206 
   11207     m_demux_entries = 0;
   11208 
   11209     while (index < bytes_to_parse) {
   11210         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   11211                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   11212                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   11213                  (buf[index+2] == 0x01)) ) {
   11214             //Found start code, insert address offset
   11215             insert_demux_addr_offset(index);
   11216             if (buf[index+2] == 0x01) // 3 byte start code
   11217                 index += 3;
   11218             else                      //4 byte start code
   11219                 index += 4;
   11220         } else
   11221             index++;
   11222     }
   11223     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
   11224     return;
   11225 }
   11226 
   11227 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   11228 {
   11229     //fix this, handle 3 byte start code, vc1 terminator entry
   11230     OMX_U8 *p_demux_data = NULL;
   11231     OMX_U32 desc_data = 0;
   11232     OMX_U32 start_addr = 0;
   11233     OMX_U32 nal_size = 0;
   11234     OMX_U32 suffix_byte = 0;
   11235     OMX_U32 demux_index = 0;
   11236     OMX_U32 buffer_index = 0;
   11237 
   11238     if (m_desc_buffer_ptr == NULL) {
   11239         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   11240         return OMX_ErrorBadParameter;
   11241     }
   11242 
   11243     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   11244     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   11245         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
   11246         return OMX_ErrorBadParameter;
   11247     }
   11248 
   11249     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   11250 
   11251     if ( ((OMX_U8*)p_demux_data == NULL) ||
   11252             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   11253         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   11254         return OMX_ErrorBadParameter;
   11255     } else {
   11256         for (; demux_index < m_demux_entries; demux_index++) {
   11257             desc_data = 0;
   11258             start_addr = m_demux_offsets[demux_index];
   11259             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   11260                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   11261             } else {
   11262                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   11263             }
   11264             if (demux_index < (m_demux_entries - 1)) {
   11265                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   11266             } else {
   11267                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   11268             }
   11269             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
   11270                     (unsigned int)start_addr,
   11271                     (unsigned int)suffix_byte,
   11272                     (unsigned int)nal_size,
   11273                     (unsigned int)demux_index);
   11274             desc_data = (start_addr >> 3) << 1;
   11275             desc_data |= (start_addr & 7) << 21;
   11276             desc_data |= suffix_byte << 24;
   11277 
   11278             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   11279             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   11280             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   11281             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   11282 
   11283             p_demux_data += 16;
   11284         }
   11285         if (codec_type_parse == CODEC_TYPE_VC1) {
   11286             DEBUG_PRINT_LOW("VC1 terminator entry");
   11287             desc_data = 0;
   11288             desc_data = 0x82 << 24;
   11289             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   11290             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   11291             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   11292             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   11293             p_demux_data += 16;
   11294             m_demux_entries++;
   11295         }
   11296         //Add zero word to indicate end of descriptors
   11297         memset(p_demux_data, 0, sizeof(OMX_U32));
   11298 
   11299         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   11300         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
   11301     }
   11302     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   11303     m_demux_entries = 0;
   11304     DEBUG_PRINT_LOW("Demux table complete!");
   11305     return OMX_ErrorNone;
   11306 }
   11307 
   11308 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level)
   11309 {
   11310     struct v4l2_control control;
   11311     char property_value[PROPERTY_VALUE_MAX] = {0};
   11312 
   11313     property_get("vidc.debug.turbo", property_value, "0");
   11314     memset(&control, 0, sizeof(v4l2_control));
   11315     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   11316     switch (perf_level) {
   11317     case VIDC_NOMINAL:
   11318         if (atoi(property_value))
   11319             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   11320         else
   11321             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   11322         break;
   11323     case VIDC_TURBO:
   11324         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   11325         break;
   11326      default:
   11327         DEBUG_PRINT_ERROR("Requested PERF level not supported");
   11328         break;
   11329     }
   11330     if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig)
   11331         return;
   11332 
   11333     DEBUG_PRINT_HIGH("changing performance level to %d", control.value);
   11334     if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11335         current_perf_level = control.value;
   11336     } else {
   11337         DEBUG_PRINT_ERROR("Failed to set PERF level");
   11338     }
   11339 }
   11340 
   11341 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   11342 {
   11343     enabled = false;
   11344     omx = NULL;
   11345     init_members();
   11346     ColorFormat = OMX_COLOR_FormatMax;
   11347     dest_format = YCbCr420P;
   11348 }
   11349 
   11350 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   11351 {
   11352     omx = reinterpret_cast<omx_vdec*>(client);
   11353 }
   11354 
   11355 void omx_vdec::allocate_color_convert_buf::init_members()
   11356 {
   11357     allocated_count = 0;
   11358     buffer_size_req = 0;
   11359     buffer_alignment_req = 0;
   11360     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   11361     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   11362     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   11363     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   11364 #ifdef USE_ION
   11365     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   11366 #endif
   11367     for (int i = 0; i < MAX_COUNT; i++)
   11368         pmem_fd[i] = -1;
   11369 }
   11370 
   11371 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   11372 {
   11373     c2d.destroy();
   11374 }
   11375 
   11376 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   11377 {
   11378     bool status = true;
   11379     unsigned int src_size = 0, destination_size = 0;
   11380     OMX_COLOR_FORMATTYPE drv_color_format;
   11381     if (!omx) {
   11382         DEBUG_PRINT_ERROR("Invalid client in color convert");
   11383         return false;
   11384     }
   11385     if (!enabled) {
   11386         DEBUG_PRINT_HIGH("No color conversion required");
   11387         return status;
   11388     }
   11389     pthread_mutex_lock(&omx->c_lock);
   11390     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   11391             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   11392         DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
   11393         status = false;
   11394         goto fail_update_buf_req;
   11395     }
   11396     c2d.close();
   11397     status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
   11398             omx->drv_ctx.video_resolution.frame_width,
   11399             NV12_128m,dest_format);
   11400     if (status) {
   11401         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   11402         if (status)
   11403             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   11404     }
   11405     if (status) {
   11406         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   11407                 !destination_size) {
   11408             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
   11409                     "driver size %u destination size %d",
   11410                     src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
   11411                     destination_size);
   11412             status = false;
   11413             c2d.close();
   11414             buffer_size_req = 0;
   11415         } else {
   11416             buffer_size_req = destination_size;
   11417             if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
   11418                 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
   11419             if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   11420                 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   11421         }
   11422     }
   11423 fail_update_buf_req:
   11424     pthread_mutex_unlock(&omx->c_lock);
   11425     return status;
   11426 }
   11427 
   11428 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   11429         OMX_COLOR_FORMATTYPE dest_color_format)
   11430 {
   11431     bool status = true;
   11432     OMX_COLOR_FORMATTYPE drv_color_format;
   11433     if (!omx) {
   11434         DEBUG_PRINT_ERROR("Invalid client in color convert");
   11435         return false;
   11436     }
   11437     pthread_mutex_lock(&omx->c_lock);
   11438     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   11439         if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   11440             drv_color_format = (OMX_COLOR_FORMATTYPE)
   11441                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   11442         else
   11443             drv_color_format = (OMX_COLOR_FORMATTYPE)
   11444                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11445      else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   11446          drv_color_format = (OMX_COLOR_FORMATTYPE)
   11447                   QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11448      } else {
   11449         DEBUG_PRINT_ERROR("Incorrect color format");
   11450         status = false;
   11451     }
   11452     if (status &&
   11453         drv_color_format != dest_color_format &&
   11454         drv_color_format != (OMX_COLOR_FORMATTYPE)
   11455                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView &&
   11456         drv_color_format != (OMX_COLOR_FORMATTYPE)
   11457                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed &&
   11458         dest_color_format != (OMX_COLOR_FORMATTYPE)
   11459                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   11460         DEBUG_PRINT_LOW("Enabling C2D");
   11461         if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
   11462            (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
   11463             DEBUG_PRINT_ERROR("Unsupported color format for c2d");
   11464             status = false;
   11465         } else {
   11466             ColorFormat = dest_color_format;
   11467             dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
   11468                     YCbCr420P : YCbCr420SP;
   11469             if (enabled)
   11470                 c2d.destroy();
   11471             enabled = false;
   11472             if (!c2d.init()) {
   11473                 DEBUG_PRINT_ERROR("open failed for c2d");
   11474                 status = false;
   11475             } else
   11476                 enabled = true;
   11477         }
   11478     } else {
   11479         if (enabled)
   11480             c2d.destroy();
   11481         enabled = false;
   11482     }
   11483     pthread_mutex_unlock(&omx->c_lock);
   11484     return status;
   11485 }
   11486 
   11487 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   11488 {
   11489     if (!omx) {
   11490         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11491         return NULL;
   11492     }
   11493     if (!enabled)
   11494         return omx->m_out_mem_ptr;
   11495     return m_out_mem_ptr_client;
   11496 }
   11497 
   11498     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   11499 (OMX_BUFFERHEADERTYPE *bufadd)
   11500 {
   11501     if (!omx) {
   11502         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11503         return NULL;
   11504     }
   11505     if (!enabled)
   11506         return bufadd;
   11507 
   11508     unsigned index = 0;
   11509     index = bufadd - omx->m_out_mem_ptr;
   11510     if (index < omx->drv_ctx.op_buf.actualcount) {
   11511         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   11512         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   11513         bool status;
   11514         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   11515             pthread_mutex_lock(&omx->c_lock);
   11516             cache_clean_buffer(index);
   11517             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   11518                     omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
   11519                     pmem_baseaddress[index], pmem_baseaddress[index]);
   11520             if (!status) {
   11521                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
   11522                 m_out_mem_ptr_client[index].nFilledLen = 0;
   11523                 pthread_mutex_unlock(&omx->c_lock);
   11524                 return &m_out_mem_ptr_client[index];
   11525             } else {
   11526                 unsigned int filledLen = 0;
   11527                 c2d.get_output_filled_length(filledLen);
   11528                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
   11529                 cache_clean_invalidate_buffer(index);
   11530             }
   11531             pthread_mutex_unlock(&omx->c_lock);
   11532         } else
   11533             m_out_mem_ptr_client[index].nFilledLen = 0;
   11534         return &m_out_mem_ptr_client[index];
   11535     }
   11536     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
   11537     return NULL;
   11538 }
   11539 
   11540     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   11541 (OMX_BUFFERHEADERTYPE *bufadd)
   11542 {
   11543     if (!omx) {
   11544         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11545         return NULL;
   11546     }
   11547     if (!enabled)
   11548         return bufadd;
   11549     unsigned index = 0;
   11550     index = bufadd - m_out_mem_ptr_client;
   11551     if (index < omx->drv_ctx.op_buf.actualcount) {
   11552         return &omx->m_out_mem_ptr[index];
   11553     }
   11554     DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
   11555     return NULL;
   11556 }
   11557     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   11558 (unsigned int &buffer_size)
   11559 {
   11560     bool status = true;
   11561     pthread_mutex_lock(&omx->c_lock);
   11562     if (!enabled)
   11563         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   11564     else {
   11565         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   11566             DEBUG_PRINT_ERROR("Get buffer size failed");
   11567             status = false;
   11568             goto fail_get_buffer_size;
   11569         }
   11570     }
   11571     if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
   11572         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   11573     if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   11574         buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   11575 fail_get_buffer_size:
   11576     pthread_mutex_unlock(&omx->c_lock);
   11577     return status;
   11578 }
   11579 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   11580         OMX_BUFFERHEADERTYPE *bufhdr)
   11581 {
   11582     unsigned int index = 0;
   11583 
   11584     if (!enabled)
   11585         return omx->free_output_buffer(bufhdr);
   11586     if (enabled && omx->is_component_secure())
   11587         return OMX_ErrorNone;
   11588     if (!allocated_count || !bufhdr) {
   11589         DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
   11590         return OMX_ErrorBadParameter;
   11591     }
   11592     index = bufhdr - m_out_mem_ptr_client;
   11593     if (index >= omx->drv_ctx.op_buf.actualcount) {
   11594         DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
   11595         return OMX_ErrorBadParameter;
   11596     }
   11597     if (pmem_fd[index] >= 0) {
   11598         munmap(pmem_baseaddress[index], buffer_size_req);
   11599         close(pmem_fd[index]);
   11600     }
   11601     pmem_fd[index] = -1;
   11602 #ifdef USE_ION
   11603     omx->free_ion_memory(&op_buf_ion_info[index]);
   11604 #endif
   11605     m_heap_ptr[index].video_heap_ptr = NULL;
   11606     if (allocated_count > 0)
   11607         allocated_count--;
   11608     else
   11609         allocated_count = 0;
   11610     if (!allocated_count) {
   11611         pthread_mutex_lock(&omx->c_lock);
   11612         c2d.close();
   11613         init_members();
   11614         pthread_mutex_unlock(&omx->c_lock);
   11615     }
   11616     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   11617 }
   11618 
   11619 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   11620         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   11621 {
   11622     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   11623     if (!enabled) {
   11624         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   11625         return eRet;
   11626     }
   11627     if (enabled && omx->is_component_secure()) {
   11628         DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
   11629                 omx->is_component_secure());
   11630         return OMX_ErrorUnsupportedSetting;
   11631     }
   11632     if (!bufferHdr || bytes > buffer_size_req) {
   11633         DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   11634         DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
   11635                 (unsigned int)buffer_size_req, (unsigned int)bytes);
   11636         return OMX_ErrorBadParameter;
   11637     }
   11638     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   11639         DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
   11640         return OMX_ErrorInsufficientResources;
   11641     }
   11642     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   11643     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   11644             port,appData,omx->drv_ctx.op_buf.buffer_size);
   11645     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   11646         DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
   11647         return eRet;
   11648     }
   11649     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   11650             (int)omx->drv_ctx.op_buf.actualcount) {
   11651         DEBUG_PRINT_ERROR("Invalid header index %ld",
   11652                (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
   11653         return OMX_ErrorUndefined;
   11654     }
   11655     unsigned int i = allocated_count;
   11656 #ifdef USE_ION
   11657     // Allocate color-conversion buffers as cached to improve software-reading
   11658     // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
   11659     // cache invalidation.
   11660     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   11661             buffer_size_req,buffer_alignment_req,
   11662             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   11663             ION_FLAG_CACHED);
   11664     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   11665     if (op_buf_ion_info[i].ion_device_fd < 0) {
   11666         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
   11667         return OMX_ErrorInsufficientResources;
   11668     }
   11669     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   11670             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   11671 
   11672     if (pmem_baseaddress[i] == MAP_FAILED) {
   11673         DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
   11674         close(pmem_fd[i]);
   11675         omx->free_ion_memory(&op_buf_ion_info[i]);
   11676         return OMX_ErrorInsufficientResources;
   11677     }
   11678     m_heap_ptr[i].video_heap_ptr = new VideoHeap (
   11679             op_buf_ion_info[i].ion_device_fd,buffer_size_req,
   11680             pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
   11681 #endif
   11682     m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get();
   11683     m_pmem_info_client[i].offset = 0;
   11684     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   11685     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   11686     m_platform_list_client[i].nEntries = 1;
   11687     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   11688     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   11689     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   11690     m_out_mem_ptr_client[i].nFilledLen = 0;
   11691     m_out_mem_ptr_client[i].nFlags = 0;
   11692     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11693     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   11694     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   11695     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   11696     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   11697     m_out_mem_ptr_client[i].pAppPrivate = appData;
   11698     *bufferHdr = &m_out_mem_ptr_client[i];
   11699     DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr);
   11700     allocated_count++;
   11701     return eRet;
   11702 }
   11703 
   11704 bool omx_vdec::is_component_secure()
   11705 {
   11706     return secure_mode;
   11707 }
   11708 
   11709 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   11710 {
   11711     bool status = true;
   11712     if (!enabled) {
   11713         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   11714             if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   11715                     dest_color_format = (OMX_COLOR_FORMATTYPE)
   11716                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   11717                 else
   11718                     dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11719         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){
   11720              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11721         } else
   11722             status = false;
   11723     } else {
   11724         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
   11725             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   11726             dest_color_format = ColorFormat;
   11727         } else
   11728             status = false;
   11729     }
   11730     return status;
   11731 }
   11732 
   11733 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
   11734         unsigned int index, unsigned int cmd)
   11735 {
   11736     if (!enabled) {
   11737         return OMX_ErrorNone;
   11738     }
   11739 
   11740     if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
   11741         DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
   11742         return OMX_ErrorBadParameter;
   11743     }
   11744 
   11745     struct ion_flush_data flush_data;
   11746     struct ion_custom_data custom_data;
   11747 
   11748     memset(&flush_data, 0x0, sizeof(flush_data));
   11749     memset(&custom_data, 0x0, sizeof(custom_data));
   11750 
   11751     flush_data.vaddr = pmem_baseaddress[index];
   11752     flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
   11753     flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
   11754     flush_data.length = buffer_size_req;
   11755     custom_data.cmd = cmd;
   11756     custom_data.arg = (unsigned long)&flush_data;
   11757 
   11758     DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
   11759             (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   11760             flush_data.fd, flush_data.handle, flush_data.vaddr,
   11761             flush_data.length);
   11762     int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
   11763     if (ret < 0) {
   11764         DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
   11765                 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   11766                 strerror(errno));
   11767         return OMX_ErrorUndefined;
   11768     }
   11769     return OMX_ErrorNone;
   11770 }
   11771 
   11772 void omx_vdec::buf_ref_add(int nPortIndex)
   11773 {
   11774     unsigned long i = 0;
   11775     bool buf_present = false;
   11776     long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   11777     OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   11778 
   11779     if (!dynamic_buf_mode || !out_dynamic_list) {
   11780         return;
   11781     }
   11782 
   11783     pthread_mutex_lock(&m_lock);
   11784     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11785         //check the buffer fd, offset, uv addr with list contents
   11786         //If present increment reference.
   11787         if ((out_dynamic_list[i].fd == fd) &&
   11788             (out_dynamic_list[i].offset == offset)) {
   11789                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
   11790                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11791                if (!secure_mode) {
   11792                    drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr;
   11793                }
   11794                buf_present = true;
   11795                break;
   11796         }
   11797     }
   11798     if (!buf_present) {
   11799         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11800             //search for a entry to insert details of the new buffer
   11801             if (out_dynamic_list[i].dup_fd < 0) {
   11802                 out_dynamic_list[i].fd = fd;
   11803                 out_dynamic_list[i].offset = offset;
   11804                 out_dynamic_list[i].dup_fd = dup(fd);
   11805                 out_dynamic_list[i].ref_count++;
   11806                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
   11807                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11808 
   11809                 if (!secure_mode) {
   11810                     drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   11811                             (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len,
   11812                                           PROT_READ|PROT_WRITE, MAP_SHARED,
   11813                                           drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   11814                     //mmap returns (void *)-1 on failure and sets error code in errno.
   11815                     if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) {
   11816                         DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno);
   11817                         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL;
   11818                         break;
   11819                     }
   11820                     out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr;
   11821                     out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len;
   11822                     DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   11823                 }
   11824                 break;
   11825             }
   11826         }
   11827     }
   11828    pthread_mutex_unlock(&m_lock);
   11829 }
   11830 
   11831 void omx_vdec::buf_ref_remove()
   11832 {
   11833     unsigned long i = 0;
   11834 
   11835     if (!dynamic_buf_mode || !out_dynamic_list) {
   11836         return;
   11837     }
   11838 
   11839     pthread_mutex_lock(&m_lock);
   11840     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11841         if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) {
   11842             DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   11843             munmap(out_dynamic_list[i].buffaddr,
   11844                         out_dynamic_list[i].mapped_size);
   11845         }
   11846 
   11847          DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
   11848                  (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11849          close(out_dynamic_list[i].dup_fd);
   11850          out_dynamic_list[i].dup_fd = -1;
   11851     }
   11852     pthread_mutex_unlock(&m_lock);
   11853 
   11854     if (out_dynamic_list) {
   11855         free(out_dynamic_list);
   11856         out_dynamic_list = NULL;
   11857     }
   11858 }
   11859 
   11860 #ifdef _MSM8974_
   11861 void omx_vdec::send_codec_config() {
   11862     if (codec_config_flag) {
   11863         unsigned long p1 = 0; // Parameter - 1
   11864         unsigned long p2 = 0; // Parameter - 2
   11865         unsigned long ident = 0;
   11866         pthread_mutex_lock(&m_lock);
   11867         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   11868         while (m_etb_q.m_size) {
   11869             m_etb_q.pop_entry(&p1,&p2,&ident);
   11870             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   11871                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   11872                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   11873                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   11874                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   11875                         omx_report_error();
   11876                     }
   11877                 } else {
   11878                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   11879                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   11880                 }
   11881             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   11882                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   11883                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   11884                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   11885                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   11886                         omx_report_error ();
   11887                     }
   11888                 } else {
   11889                     pending_input_buffers++;
   11890                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   11891                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   11892                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   11893                 }
   11894             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   11895                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   11896                         (OMX_BUFFERHEADERTYPE *)p1);
   11897                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   11898             }
   11899         }
   11900         pthread_mutex_unlock(&m_lock);
   11901     }
   11902 }
   11903 #endif
   11904 
   11905 omx_vdec::perf_control::perf_control()
   11906 {
   11907     m_perf_lib = NULL;
   11908     m_perf_handle = 0;
   11909     m_perf_lock_acquire = NULL;
   11910     m_perf_lock_release = NULL;
   11911 }
   11912 
   11913 omx_vdec::perf_control::~perf_control()
   11914 {
   11915     if (m_perf_handle != 0 && m_perf_lock_release) {
   11916         DEBUG_PRINT_LOW("NOTE2: release perf lock");
   11917         m_perf_lock_release(m_perf_handle);
   11918     }
   11919     if (m_perf_lib) {
   11920         dlclose(m_perf_lib);
   11921     }
   11922 }
   11923 
   11924 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0};
   11925 
   11926 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock;
   11927 
   11928 void omx_vdec::perf_control::send_hint_to_mpctl(bool state)
   11929 {
   11930     if (load_lib() == false) {
   11931        return;
   11932     }
   11933     m_perf_lock.lock();
   11934     /* 0x4401 maps to video decode playback hint
   11935      * in perflock, enum number is 44 and state
   11936      * being sent on perflock acquire is 01 (true)
   11937      */
   11938     int arg = 0x4401;
   11939 
   11940     if (state == true) {
   11941         mpctl_obj.vid_inst_count++;
   11942     } else if (state == false) {
   11943         mpctl_obj.vid_inst_count--;
   11944     }
   11945 
   11946     if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) {
   11947         mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
   11948         mpctl_obj.vid_acquired = true;
   11949         DEBUG_PRINT_INFO("Video slvp perflock acquired");
   11950     } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) {
   11951         m_perf_lock_release(mpctl_obj.vid_disp_handle);
   11952         mpctl_obj.vid_acquired = false;
   11953         DEBUG_PRINT_INFO("Video slvp perflock released");
   11954     }
   11955     m_perf_lock.unlock();
   11956 }
   11957 
   11958 void omx_vdec::perf_control::request_cores(int frame_duration_us)
   11959 {
   11960     if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
   11961         return;
   11962     }
   11963     bool retVal = load_lib();
   11964     if (retVal && m_perf_lock_acquire && m_perf_handle == 0) {
   11965         int arg = 0x700 /*base value*/ + 2 /*cores*/;
   11966         m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
   11967         if (m_perf_handle) {
   11968             DEBUG_PRINT_HIGH("perf lock acquired");
   11969         }
   11970     }
   11971 }
   11972 
   11973 bool omx_vdec::perf_control::load_lib()
   11974 {
   11975     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
   11976     if (m_perf_lib)
   11977         return true;
   11978 
   11979     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
   11980         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
   11981         goto handle_err;
   11982     }
   11983 
   11984     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
   11985         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
   11986         goto handle_err;
   11987     } else {
   11988         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
   11989         if (m_perf_lock_acquire == NULL) {
   11990             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
   11991             goto handle_err;
   11992         }
   11993         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
   11994         if (m_perf_lock_release == NULL) {
   11995             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
   11996             goto handle_err;
   11997         }
   11998     }
   11999     return true;
   12000 
   12001 handle_err:
   12002     if (m_perf_lib) {
   12003         dlclose(m_perf_lib);
   12004     }
   12005     m_perf_lib = NULL;
   12006     return false;
   12007 }
   12008 
   12009 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
   12010                             unsigned long nMaxFrameHeight)
   12011 {
   12012 
   12013     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12014     int ret = 0;
   12015     unsigned long min_res_buf_count = 0;
   12016 
   12017     eRet = enable_smoothstreaming();
   12018     if (eRet != OMX_ErrorNone) {
   12019          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
   12020          return eRet;
   12021      }
   12022 
   12023      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
   12024              nMaxFrameWidth,
   12025              nMaxFrameHeight);
   12026      m_smoothstreaming_mode = true;
   12027      m_smoothstreaming_width = nMaxFrameWidth;
   12028      m_smoothstreaming_height = nMaxFrameHeight;
   12029 
   12030      //Get upper limit buffer count for min supported resolution
   12031      struct v4l2_format fmt;
   12032      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   12033      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
   12034      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
   12035      fmt.fmt.pix_mp.pixelformat = output_capability;
   12036 
   12037      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   12038      if (ret) {
   12039          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
   12040                            m_decoder_capability.min_height,
   12041                            m_decoder_capability.min_width);
   12042          return OMX_ErrorUnsupportedSetting;
   12043      }
   12044 
   12045      eRet = get_buffer_req(&drv_ctx.op_buf);
   12046      if (eRet != OMX_ErrorNone) {
   12047          DEBUG_PRINT_ERROR("failed to get_buffer_req");
   12048          return eRet;
   12049      }
   12050 
   12051      min_res_buf_count = drv_ctx.op_buf.mincount;
   12052      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
   12053                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
   12054 
   12055      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
   12056                        m_smoothstreaming_width, m_smoothstreaming_height);
   12057      eRet = is_video_session_supported();
   12058      if (eRet != OMX_ErrorNone) {
   12059          DEBUG_PRINT_ERROR("video session is not supported");
   12060          return eRet;
   12061      }
   12062 
   12063      //Get upper limit buffer size for max smooth streaming resolution set
   12064      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   12065      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   12066      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   12067      fmt.fmt.pix_mp.pixelformat = output_capability;
   12068      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   12069      if (ret) {
   12070          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
   12071          return OMX_ErrorUnsupportedSetting;
   12072      }
   12073 
   12074      eRet = get_buffer_req(&drv_ctx.op_buf);
   12075      if (eRet != OMX_ErrorNone) {
   12076          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
   12077          return eRet;
   12078      }
   12079      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
   12080                      (unsigned int)drv_ctx.op_buf.buffer_size);
   12081 
   12082      drv_ctx.op_buf.mincount = min_res_buf_count;
   12083      drv_ctx.op_buf.actualcount = min_res_buf_count;
   12084      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
   12085      eRet = set_buffer_req(&drv_ctx.op_buf);
   12086      if (eRet != OMX_ErrorNone) {
   12087          DEBUG_PRINT_ERROR("failed to set_buffer_req");
   12088          return eRet;
   12089      }
   12090 
   12091      eRet = get_buffer_req(&drv_ctx.op_buf);
   12092      if (eRet != OMX_ErrorNone) {
   12093          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
   12094          return eRet;
   12095      }
   12096      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
   12097                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
   12098      return eRet;
   12099 }
   12100 
   12101 //static
   12102 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
   12103 
   12104 #ifndef FLEXYUV_SUPPORTED
   12105     return OMX_ErrorUndefined;
   12106 #else
   12107 
   12108     if (pParam == NULL) {
   12109         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
   12110         return OMX_ErrorBadParameter;
   12111     }
   12112 
   12113     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
   12114 
   12115     MediaImage *img = &(params->sMediaImage);
   12116     switch(params->eColorFormat) {
   12117         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   12118         {
   12119             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   12120             img->mNumPlanes = 3;
   12121             // mWidth and mHeight represent the W x H of the largest plane
   12122             // In our case, this happens to be the Stride x Scanlines of Y plane
   12123             img->mWidth = params->nFrameWidth;
   12124             img->mHeight = params->nFrameHeight;
   12125             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12126             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
   12127             img->mBitDepth = 8;
   12128             //Plane 0 (Y)
   12129             img->mPlane[MediaImage::Y].mOffset = 0;
   12130             img->mPlane[MediaImage::Y].mColInc = 1;
   12131             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
   12132             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
   12133             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
   12134             //Plane 1 (U)
   12135             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
   12136             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
   12137             img->mPlane[MediaImage::U].mRowInc =
   12138                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12139             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
   12140             img->mPlane[MediaImage::U].mVertSubsampling = 2;
   12141             //Plane 2 (V)
   12142             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
   12143             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
   12144             img->mPlane[MediaImage::V].mRowInc =
   12145                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12146             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
   12147             img->mPlane[MediaImage::V].mVertSubsampling = 2;
   12148             break;
   12149         }
   12150 
   12151         case OMX_COLOR_FormatYUV420Planar:
   12152         case OMX_COLOR_FormatYUV420SemiPlanar:
   12153             // We need not describe the standard OMX linear formats as these are
   12154             // understood by client. Fail this deliberately to let client fill-in
   12155             return OMX_ErrorUnsupportedSetting;
   12156 
   12157         default:
   12158             // Rest all formats which are non-linear cannot be described
   12159             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
   12160             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   12161             return OMX_ErrorNone;
   12162     };
   12163 
   12164     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
   12165     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
   12166     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
   12167     for (size_t i = 0; i < img->mNumPlanes; ++i) {
   12168         DEBUG_PRINT_LOW("    Plane[%zd] : offset=%d / xStep=%d / yStep = %d",
   12169                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
   12170     }
   12171     return OMX_ErrorNone;
   12172 #endif //FLEXYUV_SUPPORTED
   12173 }
   12174 
   12175 void omx_vdec::prefetchNewBuffers() {
   12176 
   12177     struct v4l2_decoder_cmd dec;
   12178     uint32_t prefetch_count;
   12179     uint32_t prefetch_size;
   12180     uint32_t want_size;
   12181     uint32_t have_size;
   12182     int color_fmt, rc;
   12183     uint32_t new_calculated_size;
   12184     uint32_t new_buffer_size;
   12185     uint32_t new_buffer_count;
   12186     uint32_t old_buffer_size;
   12187     uint32_t old_buffer_count;
   12188 
   12189     memset((void *)&dec, 0 , sizeof(dec));
   12190     DEBUG_PRINT_LOW("Old size : %d, count : %d, width : %u, height : %u\n",
   12191             (int)drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount,
   12192             drv_ctx.video_resolution.frame_width,
   12193             drv_ctx.video_resolution.frame_height);
   12194     dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT;
   12195     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   12196         DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno);
   12197     } else {
   12198         DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n",
   12199                 dec.raw.data[0], dec.raw.data[1]);
   12200     }
   12201 
   12202     switch ((int)drv_ctx.output_format) {
   12203     case VDEC_YUV_FORMAT_NV12:
   12204         color_fmt = COLOR_FMT_NV12;
   12205         break;
   12206     case VDEC_YUV_FORMAT_NV12_UBWC:
   12207         color_fmt = COLOR_FMT_NV12_UBWC;
   12208         break;
   12209     default:
   12210         color_fmt = -1;
   12211     }
   12212 
   12213     new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height);
   12214     DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n",
   12215             m_reconfig_width, m_reconfig_height, new_calculated_size);
   12216     new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size;
   12217     new_buffer_count = dec.raw.data[1];
   12218     old_buffer_size = drv_ctx.op_buf.buffer_size;
   12219     old_buffer_count = drv_ctx.op_buf.actualcount;
   12220 
   12221     new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count;
   12222 
   12223     prefetch_count = new_buffer_count;
   12224     prefetch_size = new_buffer_size - old_buffer_size;
   12225     want_size = new_buffer_size * new_buffer_count;
   12226     have_size = old_buffer_size * old_buffer_count;
   12227 
   12228     if (want_size > have_size) {
   12229         DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size);
   12230         DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size);
   12231 
   12232         int ion_fd = open(MEM_DEVICE, O_RDONLY);
   12233         if (ion_fd < 0) {
   12234             DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd);
   12235             return;
   12236         }
   12237 
   12238         struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data));
   12239         struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data));
   12240         struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions));
   12241         size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count);
   12242 
   12243         if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) {
   12244             DEBUG_PRINT_ERROR("prefetch data allocation failed");
   12245             goto prefetch_exit;
   12246         }
   12247 
   12248         for (uint32_t i = 0; i < prefetch_count; i++) {
   12249             sizes[i] = prefetch_size;
   12250         }
   12251 
   12252         regions[0].nr_sizes = prefetch_count;
   12253         regions[0].sizes = sizes;
   12254         regions[0].vmid = ION_FLAG_CP_PIXEL;
   12255 
   12256         prefetch_data->nr_regions = 1;
   12257         prefetch_data->regions = regions;
   12258         prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
   12259 
   12260         custom_data->cmd = ION_IOC_PREFETCH;
   12261         custom_data->arg = (unsigned long )prefetch_data;
   12262 
   12263         rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data);
   12264         if (rc) {
   12265             DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno);
   12266         }
   12267 
   12268 prefetch_exit:
   12269         close(ion_fd);
   12270         free(sizes);
   12271         free(regions);
   12272         free(prefetch_data);
   12273         free(custom_data);
   12274     }
   12275 }
   12276 
   12277