Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2017, 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 <sys/eventfd.h>
     56 #include <nativebase/nativebase.h>
     57 
     58 #if !defined(_ANDROID_) || defined(SYS_IOCTL)
     59 #include <sys/ioctl.h>
     60 #include <sys/mman.h>
     61 #endif
     62 
     63 #ifdef _ANDROID_
     64 #include <cutils/properties.h>
     65 #undef USE_EGL_IMAGE_GPU
     66 
     67 #ifdef _QUERY_DISP_RES_
     68 #include "display_config.h"
     69 #endif
     70 #endif
     71 
     72 #ifdef _USE_GLIB_
     73 #include <glib.h>
     74 #define strlcpy g_strlcpy
     75 #endif
     76 
     77 #include <qdMetaData.h>
     78 #include <gralloc_priv.h>
     79 
     80 #ifdef ANDROID_JELLYBEAN_MR2
     81 #include "QComOMXMetadata.h"
     82 #endif
     83 
     84 #ifdef USE_EGL_IMAGE_GPU
     85 #include <EGL/egl.h>
     86 #include <EGL/eglQCOM.h>
     87 #define EGL_BUFFER_HANDLE 0x4F00
     88 #define EGL_BUFFER_OFFSET 0x4F01
     89 #endif
     90 
     91 #define BUFFER_LOG_LOC "/data/vendor/media"
     92 
     93 #ifdef OUTPUT_EXTRADATA_LOG
     94 FILE *outputExtradataFile;
     95 char output_extradata_filename [] = "/data/vendor/media/extradata";
     96 #endif
     97 
     98 #define DEFAULT_FPS 30
     99 #define MAX_SUPPORTED_FPS 240
    100 #define DEFAULT_WIDTH_ALIGNMENT 128
    101 #define DEFAULT_HEIGHT_ALIGNMENT 32
    102 
    103 #define VC1_SP_MP_START_CODE        0xC5000000
    104 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
    105 #define VC1_AP_SEQ_START_CODE       0x0F010000
    106 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
    107 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
    108 #define VC1_SIMPLE_PROFILE          0
    109 #define VC1_MAIN_PROFILE            1
    110 #define VC1_ADVANCE_PROFILE         3
    111 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
    112 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
    113 #define VC1_STRUCT_C_LEN            4
    114 #define VC1_STRUCT_C_POS            8
    115 #define VC1_STRUCT_A_POS            12
    116 #define VC1_STRUCT_B_POS            24
    117 #define VC1_SEQ_LAYER_SIZE          36
    118 #define POLL_TIMEOUT 0x7fffffff
    119 
    120 #define MEM_DEVICE "/dev/ion"
    121 
    122 #ifdef _ANDROID_
    123 extern "C" {
    124 #include<utils/Log.h>
    125 }
    126 #endif//_ANDROID_
    127 
    128 #define SZ_4K 0x1000
    129 #define SZ_1M 0x100000
    130 
    131 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    132 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    133 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
    134 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
    135 
    136 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_FRAMEPACK_EXTRADATA | OMX_OUTPUTCROP_EXTRADATA \
    137                            | OMX_DISPLAY_INFO_EXTRADATA | OMX_HDR_COLOR_INFO_EXTRADATA)
    138 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
    139 
    140 #ifndef ION_FLAG_CP_BITSTREAM
    141 #define ION_FLAG_CP_BITSTREAM 0
    142 #endif
    143 
    144 #ifndef ION_FLAG_CP_PIXEL
    145 #define ION_FLAG_CP_PIXEL 0
    146 #endif
    147 
    148 #ifdef MASTER_SIDE_CP
    149 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
    150 #define SECURE_ALIGN SZ_4K
    151 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
    152 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
    153 #else //SLAVE_SIDE_CP
    154 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    155 #define SECURE_ALIGN SZ_1M
    156 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
    157 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
    158 #endif
    159 
    160 #define LUMINANCE_DIV_FACTOR 10000.0
    161 
    162 #define MIN(x,y) (((x) < (y)) ? (x) : (y))
    163 #define MAX(x,y) (((x) > (y)) ? (x) : (y))
    164 
    165 static OMX_U32 maxSmoothStreamingWidth = 1920;
    166 static OMX_U32 maxSmoothStreamingHeight = 1088;
    167 
    168 void* async_message_thread (void *input)
    169 {
    170     OMX_BUFFERHEADERTYPE *buffer;
    171     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    172     struct pollfd pfds[2];
    173     struct v4l2_buffer v4l2_buf;
    174     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    175     struct v4l2_event dqevent;
    176     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
    177     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    178     pfds[1].events = POLLIN | POLLERR;
    179     pfds[0].fd = omx->drv_ctx.video_driver_fd;
    180     pfds[1].fd = omx->m_poll_efd;
    181     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    182     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
    183     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
    184     while (!omx->async_thread_force_stop) {
    185         rc = poll(pfds, 2, POLL_TIMEOUT);
    186         if (!rc) {
    187             DEBUG_PRINT_ERROR("Poll timedout");
    188             break;
    189         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
    190             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
    191             break;
    192         }
    193         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
    194             DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
    195             break;
    196         }
    197         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
    198             struct vdec_msginfo vdec_msg;
    199             memset(&vdec_msg, 0, sizeof(vdec_msg));
    200             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    201             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    202             v4l2_buf.length = omx->drv_ctx.num_planes;
    203             v4l2_buf.m.planes = plane;
    204             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    205                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    206                 vdec_msg.status_code=VDEC_S_SUCCESS;
    207                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    208                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
    209                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
    210                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    211                     (uint64_t)v4l2_buf.timestamp.tv_usec;
    212 
    213                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    214                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    215                     break;
    216                 }
    217             }
    218         }
    219         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
    220             struct vdec_msginfo vdec_msg;
    221             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    222             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    223             v4l2_buf.length = 1;
    224             v4l2_buf.m.planes = plane;
    225             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    226                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
    227                 vdec_msg.status_code=VDEC_S_SUCCESS;
    228                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    229                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    230                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    231                     break;
    232                 }
    233             }
    234         }
    235         if (pfds[0].revents & POLLPRI) {
    236             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
    237             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
    238                 struct vdec_msginfo vdec_msg;
    239                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    240 
    241                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    242                 vdec_msg.status_code=VDEC_S_SUCCESS;
    243                 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
    244                 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
    245                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
    246                 if(ptr[2] & V4L2_EVENT_BITDEPTH_FLAG) {
    247                     omx->dpb_bit_depth = ptr[3];
    248                     DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", ptr[3]);
    249                 }
    250                 if(ptr[2] & V4L2_EVENT_PICSTRUCT_FLAG) {
    251                     omx->m_progressive = ptr[4];
    252                     DEBUG_PRINT_HIGH("VIDC Port Reconfig PicStruct change - %d", ptr[4]);
    253                 }
    254                 if(ptr[2] & V4L2_EVENT_COLOUR_SPACE_FLAG) {
    255                     if (ptr[5] == MSM_VIDC_BT2020) {
    256                         omx->m_color_space = omx_vdec::BT2020;
    257                     } else {
    258                         omx->m_color_space = omx_vdec::EXCEPT_BT2020;
    259                     }
    260                     DEBUG_PRINT_HIGH("VIDC Port Reconfig ColorSpace change - %d", omx->m_color_space);
    261                 }
    262                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    263                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    264                     break;
    265                 }
    266             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    267                 struct vdec_msginfo vdec_msg;
    268                 uint32_t flush_type = *(uint32_t *)dqevent.u.data;
    269                 // Old driver doesn't send flushType information.
    270                 // To make this backward compatible fallback to old approach
    271                 // if the flush_type is not present.
    272                 vdec_msg.status_code=VDEC_S_SUCCESS;
    273                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_OUTPUT)) {
    274                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
    275                     DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
    276                     if (omx->async_message_process(input,&vdec_msg) < 0) {
    277                         DEBUG_PRINT_HIGH("async_message_thread Exited");
    278                         break;
    279                     }
    280                 }
    281 
    282                 if (!flush_type || (flush_type & V4L2_QCOM_CMD_FLUSH_CAPTURE)) {
    283                     vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
    284                     DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
    285                     if (omx->async_message_process(input,&vdec_msg) < 0) {
    286                         DEBUG_PRINT_HIGH("async_message_thread Exited");
    287                         break;
    288                     }
    289                 }
    290             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
    291                 struct vdec_msginfo vdec_msg;
    292                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
    293                 vdec_msg.status_code=VDEC_S_SUCCESS;
    294                 DEBUG_PRINT_ERROR("HW Overload received");
    295                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    296                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    297                     break;
    298                 }
    299             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
    300                 struct vdec_msginfo vdec_msg;
    301                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
    302                 vdec_msg.status_code=VDEC_S_SUCCESS;
    303                 DEBUG_PRINT_ERROR("HW Unsupported received");
    304                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    305                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    306                     break;
    307                 }
    308             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    309                 struct vdec_msginfo vdec_msg;
    310                 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
    311                 vdec_msg.status_code = VDEC_S_SUCCESS;
    312                 DEBUG_PRINT_HIGH("SYS Error Recieved");
    313                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    314                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    315                     break;
    316                 }
    317             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
    318                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    319 
    320                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
    321             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
    322                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    323                 struct vdec_msginfo vdec_msg;
    324 
    325                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
    326 
    327                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    328                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    329                 v4l2_buf.length = omx->drv_ctx.num_planes;
    330                 v4l2_buf.m.planes = plane;
    331                 v4l2_buf.index = ptr[5];
    332                 v4l2_buf.flags = 0;
    333 
    334                 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    335                 vdec_msg.status_code = VDEC_S_SUCCESS;
    336                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
    337                 vdec_msg.msgdata.output_frame.len = 0;
    338                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
    339                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
    340                     (uint64_t)ptr[4];
    341                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    342                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
    343                     break;
    344                 }
    345             } else {
    346                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
    347                 continue;
    348             }
    349         }
    350     }
    351     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
    352     return NULL;
    353 }
    354 
    355 void* message_thread_dec(void *input)
    356 {
    357     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    358     unsigned char id;
    359     int n;
    360 
    361     fd_set readFds;
    362     int res = 0;
    363     struct timeval tv;
    364 
    365     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
    366     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
    367     while (!omx->message_thread_stop) {
    368 
    369         tv.tv_sec = 2;
    370         tv.tv_usec = 0;
    371 
    372         FD_ZERO(&readFds);
    373         FD_SET(omx->m_pipe_in, &readFds);
    374 
    375         res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
    376         if (res < 0) {
    377             DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
    378             continue;
    379         } else if (res == 0 /*timeout*/ || omx->message_thread_stop) {
    380             continue;
    381         }
    382 
    383         n = read(omx->m_pipe_in, &id, 1);
    384 
    385         if (0 == n) {
    386             break;
    387         }
    388 
    389         if (1 == n) {
    390             omx->process_event_cb(omx, id);
    391         }
    392 
    393         if ((n < 0) && (errno != EINTR)) {
    394             DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    395             break;
    396         }
    397     }
    398     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
    399     return 0;
    400 }
    401 
    402 void post_message(omx_vdec *omx, unsigned char id)
    403 {
    404     int ret_value;
    405     DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
    406     ret_value = write(omx->m_pipe_out, &id, 1);
    407     if (ret_value <= 0) {
    408         DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
    409     } else {
    410         DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    411     }
    412 }
    413 
    414 // omx_cmd_queue destructor
    415 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    416 {
    417     // Nothing to do
    418 }
    419 
    420 // omx cmd queue constructor
    421 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    422 {
    423     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    424 }
    425 
    426 // omx cmd queue insert
    427 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
    428 {
    429     bool ret = true;
    430     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    431         m_q[m_write].id       = id;
    432         m_q[m_write].param1   = p1;
    433         m_q[m_write].param2   = p2;
    434         m_write++;
    435         m_size ++;
    436         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    437             m_write = 0;
    438         }
    439     } else {
    440         ret = false;
    441         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
    442     }
    443     return ret;
    444 }
    445 
    446 // omx cmd queue pop
    447 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
    448 {
    449     bool ret = true;
    450     if (m_size > 0) {
    451         *id = m_q[m_read].id;
    452         *p1 = m_q[m_read].param1;
    453         *p2 = m_q[m_read].param2;
    454         // Move the read pointer ahead
    455         ++m_read;
    456         --m_size;
    457         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    458             m_read = 0;
    459         }
    460     } else {
    461         ret = false;
    462     }
    463     return ret;
    464 }
    465 
    466 // Retrieve the first mesg type in the queue
    467 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    468 {
    469     return m_q[m_read].id;
    470 }
    471 
    472 #ifdef _ANDROID_
    473 omx_vdec::ts_arr_list::ts_arr_list()
    474 {
    475     //initialize timestamps array
    476     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    477 }
    478 omx_vdec::ts_arr_list::~ts_arr_list()
    479 {
    480     //free m_ts_arr_list?
    481 }
    482 
    483 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
    484 {
    485     bool ret = true;
    486     bool duplicate_ts = false;
    487     int idx = 0;
    488 
    489     //insert at the first available empty location
    490     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    491         if (!m_ts_arr_list[idx].valid) {
    492             //found invalid or empty entry, save timestamp
    493             m_ts_arr_list[idx].valid = true;
    494             m_ts_arr_list[idx].timestamp = ts;
    495             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    496                     ts, idx);
    497             break;
    498         }
    499     }
    500 
    501     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
    502         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    503         ret = false;
    504     }
    505     return ret;
    506 }
    507 
    508 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    509 {
    510     bool ret = true;
    511     int min_idx = -1;
    512     OMX_TICKS min_ts = 0;
    513     int idx = 0;
    514 
    515     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    516 
    517         if (m_ts_arr_list[idx].valid) {
    518             //found valid entry, save index
    519             if (min_idx < 0) {
    520                 //first valid entry
    521                 min_ts = m_ts_arr_list[idx].timestamp;
    522                 min_idx = idx;
    523             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
    524                 min_ts = m_ts_arr_list[idx].timestamp;
    525                 min_idx = idx;
    526             }
    527         }
    528 
    529     }
    530 
    531     if (min_idx < 0) {
    532         //no valid entries found
    533         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    534         ts = 0;
    535         ret = false;
    536     } else {
    537         ts = m_ts_arr_list[min_idx].timestamp;
    538         m_ts_arr_list[min_idx].valid = false;
    539         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    540                 ts, min_idx);
    541     }
    542 
    543     return ret;
    544 
    545 }
    546 
    547 
    548 bool omx_vdec::ts_arr_list::reset_ts_list()
    549 {
    550     bool ret = true;
    551     int idx = 0;
    552 
    553     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    554     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    555         m_ts_arr_list[idx].valid = false;
    556     }
    557     return ret;
    558 }
    559 #endif
    560 
    561 // factory function executed by the core to create instances
    562 void *get_omx_component_factory_fn(void)
    563 {
    564     return (new omx_vdec);
    565 }
    566 
    567 bool is_platform_tp10capture_supported()
    568 {
    569     char platform_name[PROPERTY_VALUE_MAX] = {0};
    570     property_get("ro.board.platform", platform_name, "0");
    571     if (!strncmp(platform_name, "msm8998", 7)) {
    572         DEBUG_PRINT_HIGH("TP10 on capture port is supported");
    573         return true;
    574     }
    575     DEBUG_PRINT_HIGH("TP10 on capture port is not supported");
    576     return false;
    577 }
    578 
    579 /* ======================================================================
    580    FUNCTION
    581    omx_vdec::omx_vdec
    582 
    583    DESCRIPTION
    584    Constructor
    585 
    586    PARAMETERS
    587    None
    588 
    589    RETURN VALUE
    590    None.
    591    ========================================================================== */
    592 omx_vdec::omx_vdec(): m_error_propogated(false),
    593     m_state(OMX_StateInvalid),
    594     m_app_data(NULL),
    595     m_inp_mem_ptr(NULL),
    596     m_out_mem_ptr(NULL),
    597     m_client_output_extradata_mem_ptr(NULL),
    598     input_flush_progress (false),
    599     output_flush_progress (false),
    600     input_use_buffer (false),
    601     output_use_buffer (false),
    602     ouput_egl_buffers(false),
    603     m_use_output_pmem(OMX_FALSE),
    604     m_out_mem_region_smi(OMX_FALSE),
    605     m_out_pvt_entry_pmem(OMX_FALSE),
    606     pending_input_buffers(0),
    607     pending_output_buffers(0),
    608     m_out_bm_count(0),
    609     m_inp_bm_count(0),
    610     m_out_extradata_bm_count(0),
    611     m_inp_bPopulated(OMX_FALSE),
    612     m_out_bPopulated(OMX_FALSE),
    613     m_flags(0),
    614     m_inp_bEnabled(OMX_TRUE),
    615     m_out_bEnabled(OMX_TRUE),
    616     m_in_alloc_cnt(0),
    617     m_platform_list(NULL),
    618     m_platform_entry(NULL),
    619     m_pmem_info(NULL),
    620     h264_parser(NULL),
    621     arbitrary_bytes (true),
    622     psource_frame (NULL),
    623     pdest_frame (NULL),
    624     m_inp_heap_ptr (NULL),
    625     m_phdr_pmem_ptr(NULL),
    626     m_heap_inp_bm_count (0),
    627     codec_type_parse ((codec_type)0),
    628     first_frame_meta (true),
    629     frame_count (0),
    630     nal_count (0),
    631     nal_length(0),
    632     look_ahead_nal (false),
    633     first_frame(0),
    634     first_buffer(NULL),
    635     first_frame_size (0),
    636     m_device_file_ptr(NULL),
    637     m_vc1_profile((vc1_profile_type)0),
    638     h264_last_au_ts(LLONG_MAX),
    639     h264_last_au_flags(0),
    640     m_disp_hor_size(0),
    641     m_disp_vert_size(0),
    642     prev_ts(LLONG_MAX),
    643     prev_ts_actual(LLONG_MAX),
    644     rst_prev_ts(true),
    645     frm_int(0),
    646     m_fps_received(0),
    647     m_fps_prev(0),
    648     m_drc_enable(0),
    649     in_reconfig(false),
    650     m_display_id(NULL),
    651     client_extradata(0),
    652     m_reject_avc_1080p_mp (0),
    653 #ifdef _ANDROID_
    654     m_enable_android_native_buffers(OMX_FALSE),
    655     m_use_android_native_buffers(OMX_FALSE),
    656 #endif
    657     m_desc_buffer_ptr(NULL),
    658     secure_mode(false),
    659     allocate_native_handle(false),
    660     m_other_extradata(NULL),
    661     m_profile(0),
    662     m_need_turbo(0),
    663     client_set_fps(false),
    664     stereo_output_mode(HAL_NO_3D),
    665     m_last_rendered_TS(-1),
    666     m_queued_codec_config_count(0),
    667     current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
    668     secure_scaling_to_non_secure_opb(false),
    669     m_force_compressed_for_dpb(true),
    670     m_is_display_session(false)
    671 {
    672     m_pipe_in = -1;
    673     m_pipe_out = -1;
    674     m_poll_efd = -1;
    675     drv_ctx.video_driver_fd = -1;
    676     drv_ctx.extradata_info.ion.fd_ion_data.fd = -1;
    677     /* Assumption is that , to begin with , we have all the frames with decoder */
    678     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
    679     memset(&m_debug,0,sizeof(m_debug));
    680 #ifdef _ANDROID_
    681     char property_value[PROPERTY_VALUE_MAX] = {0};
    682     property_get("vendor.vidc.debug.level", property_value, "1");
    683     debug_level = strtoul(property_value, NULL, 16);
    684     property_value[0] = '\0';
    685 
    686     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
    687 
    688     property_get("vendor.vidc.dec.debug.perf", property_value, "0");
    689     perf_flag = atoi(property_value);
    690     if (perf_flag) {
    691         DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
    692         dec_time.start();
    693     }
    694     proc_frms = latency = 0;
    695     prev_n_filled_len = 0;
    696     property_value[0] = '\0';
    697     property_get("vendor.vidc.dec.debug.ts", property_value, "0");
    698     m_debug_timestamp = atoi(property_value);
    699     DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
    700     if (m_debug_timestamp) {
    701         time_stamp_dts.set_timestamp_reorder_mode(true);
    702         time_stamp_dts.enable_debug_print(true);
    703     }
    704 
    705     property_value[0] = '\0';
    706     property_get("vendor.vidc.dec.debug.concealedmb", property_value, "0");
    707     m_debug_concealedmb = atoi(property_value);
    708     DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
    709 
    710     property_value[0] = '\0';
    711     property_get("vendor.vidc.dec.profile.check", property_value, "0");
    712     m_reject_avc_1080p_mp = atoi(property_value);
    713     DEBUG_PRINT_HIGH("vendor.vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
    714 
    715     property_value[0] = '\0';
    716     property_get("vendor.vidc.dec.log.in", property_value, "0");
    717     m_debug.in_buffer_log = atoi(property_value);
    718 
    719     property_value[0] = '\0';
    720     property_get("vendor.vidc.dec.log.out", property_value, "0");
    721     m_debug.out_buffer_log = atoi(property_value);
    722     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    723 
    724     property_value[0] = '\0';
    725     property_get("vendor.vidc.dec.meta.log.out", property_value, "0");
    726     m_debug.out_meta_buffer_log = atoi(property_value);
    727     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    728 
    729     property_value[0] = '\0';
    730     property_get("vendor.vidc.log.loc", property_value, "");
    731     if (*property_value)
    732         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
    733 
    734     property_value[0] = '\0';
    735     property_get("vendor.vidc.dec.120fps.enabled", property_value, "0");
    736 
    737     //if this feature is not enabled then reset this value -ve
    738     if(atoi(property_value)) {
    739         DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
    740         m_last_rendered_TS = 0;
    741     }
    742 
    743     property_value[0] = '\0';
    744     property_get("vendor.vidc.dec.debug.dyn.disabled", property_value, "0");
    745     m_disable_dynamic_buf_mode = atoi(property_value);
    746     DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode);
    747 
    748     property_value[0] = '\0';
    749     property_get("vendor.vidc.dec.drc.enable", property_value, "0");
    750     if (atoi(property_value)) {
    751         m_drc_enable = true;
    752         DEBUG_PRINT_HIGH("DRC enabled");
    753     }
    754 
    755 #ifdef _UBWC_
    756     property_value[0] = '\0';
    757     property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
    758     m_disable_ubwc_mode = atoi(property_value);
    759     DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
    760 #else
    761     m_disable_ubwc_mode = true;
    762 #endif
    763 #endif
    764     memset(&m_cmp,0,sizeof(m_cmp));
    765     memset(&m_cb,0,sizeof(m_cb));
    766     memset (&drv_ctx,0,sizeof(drv_ctx));
    767     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    768     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    769     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
    770     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
    771     memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
    772     memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
    773     memset(&m_client_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
    774     memset(&m_internal_hdr_info, 0, sizeof(DescribeHDRStaticInfoParams));
    775     memset(&m_color_mdata, 0, sizeof(ColorMetaData));
    776     m_demux_entries = 0;
    777     msg_thread_id = 0;
    778     async_thread_id = 0;
    779     msg_thread_created = false;
    780     async_thread_created = false;
    781     async_thread_force_stop = false;
    782     message_thread_stop = false;
    783 #ifdef _ANDROID_ICS_
    784     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    785 #endif
    786     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
    787 
    788     /* invalidate m_frame_pack_arrangement */
    789     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
    790     m_frame_pack_arrangement.cancel_flag = 1;
    791 
    792     drv_ctx.timestamp_adjust = false;
    793     m_vendor_config.pData = NULL;
    794     pthread_mutex_init(&m_lock, NULL);
    795     pthread_mutex_init(&c_lock, NULL);
    796     pthread_mutex_init(&buf_lock, NULL);
    797     sem_init(&m_cmd_lock,0,0);
    798     sem_init(&m_safe_flush, 0, 0);
    799     streaming[CAPTURE_PORT] =
    800         streaming[OUTPUT_PORT] = false;
    801 #ifdef _ANDROID_
    802     char extradata_value[PROPERTY_VALUE_MAX] = {0};
    803     property_get("vendor.vidc.dec.debug.extradata", extradata_value, "0");
    804     m_debug_extradata = atoi(extradata_value);
    805     DEBUG_PRINT_HIGH("vendor.vidc.dec.debug.extradata value is %d",m_debug_extradata);
    806 #endif
    807     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    808     client_buffers.set_vdec_client(this);
    809     dynamic_buf_mode = false;
    810     out_dynamic_list = NULL;
    811     is_down_scalar_enabled = false;
    812     m_enable_downscalar = 0;
    813     m_downscalar_width = 0;
    814     m_downscalar_height = 0;
    815     m_force_down_scalar = 0;
    816     m_reconfig_height = 0;
    817     m_reconfig_width = 0;
    818     m_smoothstreaming_mode = false;
    819     m_smoothstreaming_width = 0;
    820     m_smoothstreaming_height = 0;
    821     m_decode_order_mode = false;
    822     is_q6_platform = false;
    823     m_perf_control.send_hint_to_mpctl(true);
    824     m_input_pass_buffer_fd = false;
    825     memset(&m_extradata_info, 0, sizeof(m_extradata_info));
    826     m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
    827     m_client_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    828     m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    829     m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    830     m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    831 
    832     m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    833     m_internal_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    834     m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    835     m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    836     m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    837     m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
    838 
    839     m_client_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_INPUT_PORT_INDEX;
    840     m_internal_hdr_info.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    841     m_change_client_hdr_info = false;
    842     pthread_mutex_init(&m_hdr_info_client_lock, NULL);
    843 
    844     char dither_value[PROPERTY_VALUE_MAX] = {0};
    845     property_get("vendor.vidc.dec.dither", dither_value, "0");
    846     if ((atoi(dither_value) > DITHER_ALL_COLORSPACE) ||
    847         (atoi(dither_value) < DITHER_DISABLE)) {
    848         m_dither_config = DITHER_ALL_COLORSPACE;
    849     } else {
    850         m_dither_config = is_platform_tp10capture_supported() ? (dither_type)atoi(dither_value) : DITHER_ALL_COLORSPACE;
    851     }
    852 
    853     DEBUG_PRINT_HIGH("Dither config is %d", m_dither_config);
    854     m_color_space = EXCEPT_BT2020;
    855 }
    856 
    857 static const int event_type[] = {
    858     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    859     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
    860     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
    861     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT,
    862     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
    863     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
    864     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
    865     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
    866     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
    867 };
    868 
    869 static OMX_ERRORTYPE subscribe_to_events(int fd)
    870 {
    871     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    872     struct v4l2_event_subscription sub;
    873     int array_sz = sizeof(event_type)/sizeof(int);
    874     int i,rc;
    875     if (fd < 0) {
    876         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    877         return OMX_ErrorBadParameter;
    878     }
    879 
    880     for (i = 0; i < array_sz; ++i) {
    881         memset(&sub, 0, sizeof(sub));
    882         sub.type = event_type[i];
    883         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    884         if (rc) {
    885             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    886             break;
    887         }
    888     }
    889     if (i < array_sz) {
    890         for (--i; i >=0 ; i--) {
    891             memset(&sub, 0, sizeof(sub));
    892             sub.type = event_type[i];
    893             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    894             if (rc)
    895                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    896         }
    897         eRet = OMX_ErrorNotImplemented;
    898     }
    899     return eRet;
    900 }
    901 
    902 
    903 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    904 {
    905     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    906     struct v4l2_event_subscription sub;
    907     int array_sz = sizeof(event_type)/sizeof(int);
    908     int i,rc;
    909     if (fd < 0) {
    910         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    911         return OMX_ErrorBadParameter;
    912     }
    913 
    914     for (i = 0; i < array_sz; ++i) {
    915         memset(&sub, 0, sizeof(sub));
    916         sub.type = event_type[i];
    917         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    918         if (rc) {
    919             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    920             break;
    921         }
    922     }
    923     return eRet;
    924 }
    925 
    926 /* ======================================================================
    927    FUNCTION
    928    omx_vdec::~omx_vdec
    929 
    930    DESCRIPTION
    931    Destructor
    932 
    933    PARAMETERS
    934    None
    935 
    936    RETURN VALUE
    937    None.
    938    ========================================================================== */
    939 omx_vdec::~omx_vdec()
    940 {
    941     m_pmem_info = NULL;
    942     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
    943     if (msg_thread_created) {
    944         DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
    945         message_thread_stop = true;
    946         post_message(this, OMX_COMPONENT_CLOSE_MSG);
    947         DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    948         pthread_join(msg_thread_id,NULL);
    949     }
    950     close(m_pipe_in);
    951     close(m_pipe_out);
    952     m_pipe_in = -1;
    953     m_pipe_out = -1;
    954     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    955     if(eventfd_write(m_poll_efd, 1)) {
    956          DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
    957          async_thread_force_stop = true;
    958     }
    959 
    960     if (async_thread_created)
    961         pthread_join(async_thread_id,NULL);
    962     unsubscribe_to_events(drv_ctx.video_driver_fd);
    963     close(m_poll_efd);
    964     close(drv_ctx.video_driver_fd);
    965     pthread_mutex_destroy(&m_lock);
    966     pthread_mutex_destroy(&c_lock);
    967     pthread_mutex_destroy(&buf_lock);
    968     sem_destroy(&m_cmd_lock);
    969     pthread_mutex_destroy(&m_hdr_info_client_lock);
    970     if (perf_flag) {
    971         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
    972         dec_time.end();
    973     }
    974     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
    975     m_perf_control.send_hint_to_mpctl(false);
    976 }
    977 
    978 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
    979 {
    980     struct v4l2_requestbuffers bufreq;
    981     int rc = 0;
    982     if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
    983         bufreq.memory = V4L2_MEMORY_USERPTR;
    984         bufreq.count = 0;
    985         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    986         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    987     } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
    988         bufreq.memory = V4L2_MEMORY_USERPTR;
    989         bufreq.count = 0;
    990         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    991         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    992     }
    993     return rc;
    994 }
    995 
    996 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format)
    997 {
    998     int rc = 0;
    999     struct v4l2_ext_control ctrl[2];
   1000     struct v4l2_ext_controls controls;
   1001 
   1002     DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s",
   1003          is_split_mode ? "split" : "combined",
   1004          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc":
   1005          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc":
   1006          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb":
   1007          "unknown",
   1008          capture_capability == V4L2_PIX_FMT_NV12 ? "nv12":
   1009          capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc":
   1010          capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC ? "nv12_10bit_ubwc":
   1011          "unknown");
   1012 
   1013     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
   1014     if (is_split_mode) {
   1015         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
   1016     } else {
   1017         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
   1018     }
   1019 
   1020     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
   1021     ctrl[1].value = dpb_color_format;
   1022 
   1023     controls.count = 2;
   1024     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
   1025     controls.controls = ctrl;
   1026 
   1027     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
   1028     if (rc) {
   1029         DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
   1030         return OMX_ErrorUnsupportedSetting;
   1031     }
   1032     return OMX_ErrorNone;
   1033 }
   1034 
   1035 
   1036 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool split_opb_dpb_with_same_color_fmt)
   1037 {
   1038     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1039     struct v4l2_format fmt;
   1040     int rc = 0;
   1041     bool cpu_access = (capture_capability != V4L2_PIX_FMT_NV12_UBWC) &&
   1042         capture_capability != V4L2_PIX_FMT_NV12_TP10_UBWC;
   1043     bool tp10_enable = !drv_ctx.idr_only_decoding &&
   1044         !client_buffers.is_color_conversion_enabled() &&
   1045         dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10;
   1046     bool dither_enable = true;
   1047 
   1048     switch (m_dither_config) {
   1049     case DITHER_DISABLE:
   1050         dither_enable = false;
   1051         break;
   1052     case DITHER_COLORSPACE_EXCEPTBT2020:
   1053         dither_enable = (m_color_space == EXCEPT_BT2020);
   1054         break;
   1055     case DITHER_ALL_COLORSPACE:
   1056         dither_enable = true;
   1057         break;
   1058     default:
   1059         DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config);
   1060     }
   1061 
   1062     if (tp10_enable && !dither_enable) {
   1063         drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
   1064         capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
   1065         cpu_access = false;
   1066 
   1067         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1068         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1069         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1070         if (rc) {
   1071             DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__);
   1072             return OMX_ErrorUnsupportedSetting;
   1073         }
   1074         fmt.fmt.pix_mp.pixelformat = capture_capability;
   1075         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1076         if (rc) {
   1077             DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1078             return OMX_ErrorUnsupportedSetting;
   1079         }
   1080     }
   1081 
   1082 
   1083     if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
   1084         !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   1085         DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
   1086         return eRet;
   1087     }
   1088 
   1089 
   1090     if (cpu_access) {
   1091         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1092             /* Disabled split mode for VP9. In split mode the DPB buffers are part of the internal
   1093              * scratch buffers and the driver does not does the reference buffer management for
   1094              * scratch buffers. In case of VP9 with spatial scalability, when a sequence changed
   1095              * event is received with the new resolution, and when a flush is sent by the driver, it
   1096              * releases all the references of internal scratch buffers. However as per the VP9
   1097              * spatial scalability, even after the flush, the buffers which have not yet received
   1098              * release reference event should not be unmapped and freed. Currently in driver,
   1099              * reference buffer management of the internal scratch buffer is not implemented
   1100              * and hence the DPB buffers get unmapped. For other codecs it does not matter
   1101              * as with the new SPS/PPS, the DPB is flushed.
   1102              */
   1103             bool is_not_vp9 = eCompressionFormat != OMX_VIDEO_CodingVP9;
   1104             bool eligible_for_split_dpb_ubwc =
   1105                m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE &&     //@ Due to Venus limitation for Interlaced, Split mode enabled only for Progressive.
   1106                is_not_vp9                                       &&     //@ Split mode disabled for VP9.
   1107                !drv_ctx.idr_only_decoding                       &&     //@ Split mode disabled for Thumbnail usecase.
   1108                !m_disable_split_mode;                                  //@ Set prop to disable split mode
   1109 
   1110             //Since opb is linear, dpb should also be linear.
   1111             if (split_opb_dpb_with_same_color_fmt) {
   1112                 eligible_for_split_dpb_ubwc = false;
   1113             }
   1114 
   1115             if (eligible_for_split_dpb_ubwc) {
   1116                 //split DPB-OPB
   1117                 //DPB -> UBWC , OPB -> Linear
   1118                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1119             } else if (split_opb_dpb_with_same_color_fmt) {
   1120                         //DPB -> Linear, OPB -> Linear
   1121                         eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1122             } else {
   1123                         //DPB-OPB combined linear
   1124                         eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1125            }
   1126         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1127             //split DPB-OPB
   1128             //DPB -> UBWC, OPB -> Linear
   1129             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1130         }
   1131     } else { //no cpu access
   1132         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1133             if (split_opb_dpb_with_same_color_fmt) {
   1134                 //split DPB-OPB
   1135                 //DPB -> UBWC, OPB -> UBWC
   1136                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1137             } else {
   1138                 //DPB-OPB combined UBWC
   1139                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1140             }
   1141         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1142             if (dither_enable) {
   1143                 //split DPB-OPB
   1144                 //DPB -> TP10UBWC, OPB -> UBWC
   1145                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1146             } else {
   1147                 //combined DPB-OPB
   1148                 //DPB -> TP10UBWC, OPB -> TP10UBWC
   1149                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1150             }
   1151         }
   1152     }
   1153     if (eRet) {
   1154         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
   1155     }
   1156 
   1157 
   1158 
   1159     return eRet;
   1160 }
   1161 
   1162 int omx_vdec::enable_downscalar()
   1163 {
   1164     int rc = 0;
   1165     struct v4l2_control control;
   1166     struct v4l2_format fmt;
   1167 
   1168     if (is_down_scalar_enabled) {
   1169         DEBUG_PRINT_LOW("%s: already enabled", __func__);
   1170         return 0;
   1171     }
   1172 
   1173     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
   1174     rc = decide_dpb_buffer_mode(true);
   1175     if (rc) {
   1176         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
   1177         return rc;
   1178     }
   1179     is_down_scalar_enabled = true;
   1180 
   1181     memset(&control, 0x0, sizeof(struct v4l2_control));
   1182     control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
   1183     control.value = 1;
   1184     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1185     if (rc) {
   1186         DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__);
   1187         return rc;
   1188     }
   1189 
   1190     return 0;
   1191 }
   1192 
   1193 int omx_vdec::disable_downscalar()
   1194 {
   1195     int rc = 0;
   1196     struct v4l2_control control;
   1197 
   1198     if (!is_down_scalar_enabled) {
   1199         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
   1200         return 0;
   1201     }
   1202 
   1203     rc = decide_dpb_buffer_mode(false);
   1204     if (rc < 0) {
   1205         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
   1206         return rc;
   1207     }
   1208     is_down_scalar_enabled = false;
   1209 
   1210     return rc;
   1211 }
   1212 
   1213 int omx_vdec::decide_downscalar()
   1214 {
   1215     int rc = 0;
   1216     struct v4l2_format fmt;
   1217     enum color_fmts color_format;
   1218     OMX_U32 width, height;
   1219     OMX_BOOL isPortraitVideo = OMX_FALSE;
   1220 
   1221     if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
   1222         rc = disable_downscalar();
   1223         if (rc) {
   1224             DEBUG_PRINT_ERROR("Disable downscalar failed!");
   1225             return rc;
   1226         }
   1227         return 0;
   1228     }
   1229 
   1230     if  (!m_enable_downscalar) {
   1231         DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
   1232         return 0;
   1233     }
   1234 
   1235 #ifdef _QUERY_DISP_RES_
   1236     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1237     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1238     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1239     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1240     if (rc < 0) {
   1241        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1242        return rc;
   1243     }
   1244     isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
   1245     if (!m_downscalar_width || !m_downscalar_height) {
   1246         qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
   1247         int prim_config, ext_config, virt_config;
   1248 
   1249         prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
   1250         dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
   1251         DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d  dpa.yres=%d   dpa.xdpi = %f  dpa.ydpi = %f ",
   1252             __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
   1253 
   1254         ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
   1255         dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
   1256         DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d  dsa.yres = %d   dsa.xdpi = %f  dsa.ydpi = %f ",
   1257             __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
   1258 
   1259         virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
   1260         dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
   1261         DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d  dva.yres = %d   dva.xdpi = %f  dva.ydpi = %f ",
   1262             __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
   1263 
   1264         /* Below logic takes care of following conditions:
   1265          *   1. Choose display resolution as maximum resolution of all the connected
   1266          *      displays (secondary, primary, virtual), so that we do not downscale
   1267          *      unnecessarily which might be supported on one of the display losing quality.
   1268          *   2. Displays connected might be in landscape or portrait mode, so the xres might
   1269          *      be smaller or greater than the yres. So we first take the max of the two
   1270          *      in width and min of two in height and then rotate it if below point is true.
   1271          *   3. Video might also be in portrait mode, so invert the downscalar width and
   1272          *      height for such cases.
   1273          */
   1274         if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
   1275             m_downscalar_width = MAX(dsa.xres, dsa.yres);
   1276             m_downscalar_height = MIN(dsa.xres, dsa.yres);
   1277         } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
   1278             m_downscalar_width = MAX(dva.xres, dva.yres);
   1279             m_downscalar_height = MIN(dva.xres, dva.yres);
   1280 
   1281         } else {
   1282             m_downscalar_width = MAX(dpa.xres, dpa.yres);
   1283             m_downscalar_height = MIN(dpa.xres, dpa.yres);
   1284         }
   1285         if (isPortraitVideo) {
   1286             // Swap width and height
   1287             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
   1288             m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
   1289             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
   1290         }
   1291     }
   1292     m_downscalar_width = ALIGN(m_downscalar_width, 128);
   1293     m_downscalar_height = ALIGN(m_downscalar_height, 32);
   1294 #endif
   1295 
   1296     if (!m_downscalar_width || !m_downscalar_height) {
   1297         DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
   1298         return 0;
   1299     }
   1300 
   1301     if (m_force_down_scalar) {
   1302         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
   1303         return 0;
   1304     }
   1305 
   1306     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1307     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1308     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1309     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1310     if (rc < 0) {
   1311        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1312        return rc;
   1313     }
   1314 
   1315     height = fmt.fmt.pix_mp.height;
   1316     width = fmt.fmt.pix_mp.width;
   1317 
   1318     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
   1319         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
   1320 
   1321     if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) &&
   1322          m_is_display_session) {
   1323         rc = enable_downscalar();
   1324         if (rc < 0) {
   1325             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   1326             return rc;
   1327         }
   1328 
   1329         width = m_downscalar_width > fmt.fmt.pix_mp.width ?
   1330                             fmt.fmt.pix_mp.width : m_downscalar_width;
   1331         height = m_downscalar_height > fmt.fmt.pix_mp.height ?
   1332                             fmt.fmt.pix_mp.height : m_downscalar_height;
   1333         switch (capture_capability) {
   1334             case V4L2_PIX_FMT_NV12:
   1335                 color_format = COLOR_FMT_NV12;
   1336                 break;
   1337             case V4L2_PIX_FMT_NV12_UBWC:
   1338                 color_format = COLOR_FMT_NV12_UBWC;
   1339                 break;
   1340             case V4L2_PIX_FMT_NV12_TP10_UBWC:
   1341                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
   1342                 break;
   1343             default:
   1344                 DEBUG_PRINT_ERROR("Color format not recognized\n");
   1345                 rc = OMX_ErrorUndefined;
   1346                 return rc;
   1347         }
   1348     } else {
   1349 
   1350         rc = disable_downscalar();
   1351         if (rc < 0) {
   1352             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   1353             return rc;
   1354         }
   1355     }
   1356 
   1357     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1358     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1359     fmt.fmt.pix_mp.height = height;
   1360     fmt.fmt.pix_mp.width = width;
   1361     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1362     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1363     if (rc) {
   1364         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1365         return rc;
   1366     }
   1367 
   1368     rc = get_buffer_req(&drv_ctx.op_buf);
   1369     if (rc) {
   1370         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
   1371         return rc;
   1372     }
   1373 
   1374     return rc;
   1375 }
   1376 
   1377 /* ======================================================================
   1378    FUNCTION
   1379    omx_vdec::OMXCntrlProcessMsgCb
   1380 
   1381    DESCRIPTION
   1382    IL Client callbacks are generated through this routine. The decoder
   1383    provides the thread context for this routine.
   1384 
   1385    PARAMETERS
   1386    ctxt -- Context information related to the self.
   1387    id   -- Event identifier. This could be any of the following:
   1388    1. Command completion event
   1389    2. Buffer done callback event
   1390    3. Frame done callback event
   1391 
   1392    RETURN VALUE
   1393    None.
   1394 
   1395    ========================================================================== */
   1396 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
   1397 {
   1398     unsigned long p1; // Parameter - 1
   1399     unsigned long p2; // Parameter - 2
   1400     unsigned long ident;
   1401     unsigned qsize=0; // qsize
   1402     omx_vdec *pThis = (omx_vdec *) ctxt;
   1403 
   1404     if (!pThis) {
   1405         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
   1406                 __func__);
   1407         return;
   1408     }
   1409 
   1410     // Protect the shared queue data structure
   1411     do {
   1412         /*Read the message id's from the queue*/
   1413         pthread_mutex_lock(&pThis->m_lock);
   1414         qsize = pThis->m_cmd_q.m_size;
   1415         if (qsize) {
   1416             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
   1417         }
   1418 
   1419         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1420             qsize = pThis->m_ftb_q.m_size;
   1421             if (qsize) {
   1422                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
   1423             }
   1424         }
   1425 
   1426         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1427             qsize = pThis->m_etb_q.m_size;
   1428             if (qsize) {
   1429                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
   1430             }
   1431         }
   1432         pthread_mutex_unlock(&pThis->m_lock);
   1433 
   1434         /*process message if we have one*/
   1435         if (qsize > 0) {
   1436             id = ident;
   1437             switch (id) {
   1438                 case OMX_COMPONENT_GENERATE_EVENT:
   1439                     if (pThis->m_cb.EventHandler) {
   1440                         switch (p1) {
   1441                             case OMX_CommandStateSet:
   1442                                 pThis->m_state = (OMX_STATETYPE) p2;
   1443                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
   1444                                         pThis->m_state);
   1445                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1446                                         OMX_EventCmdComplete, p1, p2, NULL);
   1447                                 break;
   1448 
   1449                             case OMX_EventError:
   1450                                 if (p2 == OMX_StateInvalid) {
   1451                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
   1452                                     pThis->m_state = (OMX_STATETYPE) p2;
   1453                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1454                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
   1455                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
   1456                                     pThis->omx_report_error();
   1457                                 } else {
   1458                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1459                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
   1460                                 }
   1461                                 break;
   1462 
   1463                             case OMX_CommandPortDisable:
   1464                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
   1465                                 if (BITMASK_PRESENT(&pThis->m_flags,
   1466                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1467                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1468                                     break;
   1469                                 }
   1470                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
   1471                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1472                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   1473                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
   1474                                         DEBUG_PRINT_HIGH("Failed to release output buffers");
   1475                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
   1476                                     if (eRet !=  OMX_ErrorNone) {
   1477                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
   1478                                         pThis->omx_report_error();
   1479                                         break;
   1480                                     }
   1481                                 }
   1482                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1483                                         OMX_EventCmdComplete, p1, p2, NULL );
   1484                                 break;
   1485                             case OMX_CommandPortEnable:
   1486                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
   1487                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
   1488                                         OMX_EventCmdComplete, p1, p2, NULL );
   1489                                 pThis->in_reconfig = false;
   1490                                 break;
   1491 
   1492                             default:
   1493                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1494                                         OMX_EventCmdComplete, p1, p2, NULL );
   1495                                 break;
   1496 
   1497                         }
   1498                     } else {
   1499                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1500                     }
   1501                     break;
   1502                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
   1503                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   1504                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1505                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
   1506                         pThis->omx_report_error ();
   1507                     }
   1508                     break;
   1509                 case OMX_COMPONENT_GENERATE_ETB: {
   1510                         OMX_ERRORTYPE iret;
   1511                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
   1512                         if (iret == OMX_ErrorInsufficientResources) {
   1513                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
   1514                             pThis->omx_report_hw_overload ();
   1515                         } else if (iret != OMX_ErrorNone) {
   1516                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
   1517                             pThis->omx_report_error ();
   1518                         }
   1519                     }
   1520                     break;
   1521 
   1522                 case OMX_COMPONENT_GENERATE_FTB:
   1523                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
   1524                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1525                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
   1526                         pThis->omx_report_error ();
   1527                     }
   1528                     break;
   1529 
   1530                 case OMX_COMPONENT_GENERATE_COMMAND:
   1531                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
   1532                             (OMX_U32)p2,(OMX_PTR)NULL);
   1533                     break;
   1534 
   1535                 case OMX_COMPONENT_GENERATE_EBD:
   1536 
   1537                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
   1538                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
   1539                         pThis->omx_report_error ();
   1540                     } else {
   1541                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
   1542                             pThis->time_stamp_dts.remove_time_stamp(
   1543                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
   1544                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1545                                     ?true:false);
   1546                         }
   1547 
   1548                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1549                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
   1550                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
   1551                             pThis->omx_report_error ();
   1552                         }
   1553                     }
   1554                     break;
   1555                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
   1556                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
   1557                                             if (p1) {
   1558                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
   1559                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1560                                                         ?true:false);
   1561                                                 free(timestamp);
   1562                                             }
   1563                                         }
   1564                                         break;
   1565                 case OMX_COMPONENT_GENERATE_FBD:
   1566                                         if (p2 != VDEC_S_SUCCESS) {
   1567                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
   1568                                             pThis->omx_report_error ();
   1569                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1570                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
   1571                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
   1572                                             pThis->omx_report_error ();
   1573                                         }
   1574                                         break;
   1575 
   1576                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1577                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
   1578                                         if (!pThis->input_flush_progress) {
   1579                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1580                                         } else {
   1581                                             pThis->execute_input_flush();
   1582                                             if (pThis->m_cb.EventHandler) {
   1583                                                 if (p2 != VDEC_S_SUCCESS) {
   1584                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1585                                                     pThis->omx_report_error ();
   1586                                                 } else {
   1587                                                     /*Check if we need generate event for Flush done*/
   1588                                                     pThis->notify_flush_done(ctxt);
   1589 
   1590                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1591                                                                 OMX_COMPONENT_IDLE_PENDING)) {
   1592                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1593                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
   1594                                                             pThis->omx_report_error ();
   1595                                                         } else {
   1596                                                             pThis->streaming[OUTPUT_PORT] = false;
   1597                                                         }
   1598                                                         if (!pThis->output_flush_progress) {
   1599                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
   1600                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1601                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1602                                                         }
   1603                                                     }
   1604                                                 }
   1605                                             } else {
   1606                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1607                                             }
   1608                                         }
   1609                                         break;
   1610 
   1611                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1612                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
   1613                                         if (!pThis->output_flush_progress) {
   1614                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1615                                         } else {
   1616                                             pThis->execute_output_flush();
   1617                                             if (pThis->m_cb.EventHandler) {
   1618                                                 if (p2 != VDEC_S_SUCCESS) {
   1619                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1620                                                     pThis->omx_report_error ();
   1621                                                 } else {
   1622                                                     /*Check if we need generate event for Flush done*/
   1623                                                     pThis->notify_flush_done(ctxt);
   1624 
   1625                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1626                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1627                                                         DEBUG_PRINT_LOW("Internal flush complete");
   1628                                                         BITMASK_CLEAR (&pThis->m_flags,
   1629                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1630                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1631                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1632                                                             pThis->post_event(OMX_CommandPortDisable,
   1633                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1634                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1635                                                             BITMASK_CLEAR (&pThis->m_flags,
   1636                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1637                                                             BITMASK_CLEAR (&pThis->m_flags,
   1638                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1639 
   1640                                                         }
   1641                                                     }
   1642 
   1643                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1644                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1645                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
   1646                                                             pThis->omx_report_error ();
   1647                                                             break;
   1648                                                         }
   1649                                                         pThis->streaming[CAPTURE_PORT] = false;
   1650                                                         if (!pThis->input_flush_progress) {
   1651                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
   1652                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1653                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1654                                                         }
   1655                                                     }
   1656                                                 }
   1657                                             } else {
   1658                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1659                                             }
   1660                                         }
   1661                                         break;
   1662 
   1663                 case OMX_COMPONENT_GENERATE_START_DONE:
   1664                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1665 
   1666                                         if (pThis->m_cb.EventHandler) {
   1667                                             if (p2 != VDEC_S_SUCCESS) {
   1668                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
   1669                                                 pThis->omx_report_error ();
   1670                                             } else {
   1671                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
   1672                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1673                                                     DEBUG_PRINT_LOW("Move to executing");
   1674                                                     // Send the callback now
   1675                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1676                                                     pThis->m_state = OMX_StateExecuting;
   1677                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1678                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1679                                                             OMX_StateExecuting, NULL);
   1680                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1681                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1682                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1683                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1684                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
   1685                                                         pThis->omx_report_error ();
   1686                                                     }
   1687                                                 }
   1688                                             }
   1689                                         } else {
   1690                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
   1691                                         }
   1692                                         break;
   1693 
   1694                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1695                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1696                                         if (pThis->m_cb.EventHandler) {
   1697                                             if (p2 != VDEC_S_SUCCESS) {
   1698                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1699                                                 pThis->omx_report_error ();
   1700                                             } else {
   1701                                                 pThis->complete_pending_buffer_done_cbs();
   1702                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1703                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1704                                                     //Send the callback now
   1705                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1706                                                     pThis->m_state = OMX_StatePause;
   1707                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1708                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1709                                                             OMX_StatePause, NULL);
   1710                                                 }
   1711                                             }
   1712                                         } else {
   1713                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1714                                         }
   1715 
   1716                                         break;
   1717 
   1718                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1719                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1720                                         if (pThis->m_cb.EventHandler) {
   1721                                             if (p2 != VDEC_S_SUCCESS) {
   1722                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1723                                                 pThis->omx_report_error ();
   1724                                             } else {
   1725                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1726                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
   1727                                                     // Send the callback now
   1728                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1729                                                     pThis->m_state = OMX_StateExecuting;
   1730                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1731                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1732                                                             OMX_StateExecuting,NULL);
   1733                                                 }
   1734                                             }
   1735                                         } else {
   1736                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1737                                         }
   1738 
   1739                                         break;
   1740 
   1741                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1742                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1743                                         if (pThis->m_cb.EventHandler) {
   1744                                             if (p2 != VDEC_S_SUCCESS) {
   1745                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1746                                                 pThis->omx_report_error ();
   1747                                             } else {
   1748                                                 pThis->complete_pending_buffer_done_cbs();
   1749                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1750                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1751                                                     // Send the callback now
   1752                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1753                                                     pThis->m_state = OMX_StateIdle;
   1754                                                     DEBUG_PRINT_LOW("Move to Idle State");
   1755                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1756                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1757                                                             OMX_StateIdle,NULL);
   1758                                                 }
   1759                                             }
   1760                                         } else {
   1761                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1762                                         }
   1763 
   1764                                         break;
   1765 
   1766                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1767                                         if (p2 == OMX_IndexParamPortDefinition) {
   1768                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
   1769                                             pThis->in_reconfig = true;
   1770                                             pThis->m_need_turbo &= ~TURBO_MODE_HIGH_FPS;
   1771                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
   1772                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
   1773 
   1774                                             /* Check if resolution is changed in smooth streaming mode */
   1775                                             if (pThis->m_smoothstreaming_mode &&
   1776                                                 (pThis->framesize.nWidth !=
   1777                                                     pThis->drv_ctx.video_resolution.frame_width) ||
   1778                                                 (pThis->framesize.nHeight !=
   1779                                                     pThis->drv_ctx.video_resolution.frame_height)) {
   1780 
   1781                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
   1782                                                         pThis->framesize.nWidth,
   1783                                                         pThis->framesize.nHeight,
   1784                                                         pThis->drv_ctx.video_resolution.frame_width,
   1785                                                         pThis->drv_ctx.video_resolution.frame_height);
   1786 
   1787                                                 /* Update new resolution */
   1788                                                 pThis->framesize.nWidth =
   1789                                                        pThis->drv_ctx.video_resolution.frame_width;
   1790                                                 pThis->framesize.nHeight =
   1791                                                        pThis->drv_ctx.video_resolution.frame_height;
   1792 
   1793                                                 /* Update C2D with new resolution */
   1794                                                 if (!pThis->client_buffers.update_buffer_req()) {
   1795                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
   1796                                                 }
   1797                                             }
   1798 
   1799                                             /* Update new crop information */
   1800                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
   1801                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
   1802                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
   1803                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
   1804 
   1805                                             /* Validate the new crop information */
   1806                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
   1807                                                 pThis->drv_ctx.video_resolution.frame_width) {
   1808 
   1809                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
   1810                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
   1811                                                         pThis->drv_ctx.video_resolution.frame_width);
   1812                                                 pThis->rectangle.nLeft = 0;
   1813 
   1814                                                 if (pThis->rectangle.nWidth >
   1815                                                     pThis->drv_ctx.video_resolution.frame_width) {
   1816 
   1817                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
   1818                                                             pThis->rectangle.nWidth,
   1819                                                             pThis->drv_ctx.video_resolution.frame_width);
   1820                                                     pThis->rectangle.nWidth =
   1821                                                         pThis->drv_ctx.video_resolution.frame_width;
   1822                                                 }
   1823                                             }
   1824                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
   1825                                                 pThis->drv_ctx.video_resolution.frame_height) {
   1826 
   1827                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
   1828                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
   1829                                                     pThis->drv_ctx.video_resolution.frame_height);
   1830                                                 pThis->rectangle.nTop = 0;
   1831 
   1832                                                 if (pThis->rectangle.nHeight >
   1833                                                     pThis->drv_ctx.video_resolution.frame_height) {
   1834 
   1835                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
   1836                                                         pThis->rectangle.nHeight,
   1837                                                         pThis->drv_ctx.video_resolution.frame_height);
   1838                                                     pThis->rectangle.nHeight =
   1839                                                         pThis->drv_ctx.video_resolution.frame_height;
   1840                                                 }
   1841                                             }
   1842                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
   1843                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
   1844                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
   1845                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
   1846                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
   1847                                         } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) {
   1848                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo");
   1849                                         } else {
   1850                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
   1851                                             break;
   1852                                         }
   1853                                         if (pThis->m_debug.outfile) {
   1854                                             fclose(pThis->m_debug.outfile);
   1855                                             pThis->m_debug.outfile = NULL;
   1856                                         }
   1857                                         if (pThis->m_debug.out_ymeta_file) {
   1858                                             fclose(pThis->m_debug.out_ymeta_file);
   1859                                             pThis->m_debug.out_ymeta_file = NULL;
   1860                                         }
   1861                                         if (pThis->m_debug.out_uvmeta_file) {
   1862                                             fclose(pThis->m_debug.out_uvmeta_file);
   1863                                             pThis->m_debug.out_uvmeta_file = NULL;
   1864                                         }
   1865 
   1866                                         if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) {
   1867                                             pThis->prefetchNewBuffers();
   1868                                         }
   1869 
   1870                                         if (pThis->m_cb.EventHandler) {
   1871                                             uint32_t frame_data[7];
   1872                                             frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ?
   1873                                                 pThis->m_reconfig_height : pThis->rectangle.nHeight;
   1874                                             frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ?
   1875                                                 pThis->m_reconfig_width : pThis->rectangle.nWidth;
   1876 
   1877                                             frame_data[2] = (p2 == OMX_IndexParamPortDefinition) ?
   1878                                                 frame_data[0] : pThis->drv_ctx.video_resolution.frame_height;
   1879 
   1880                                             frame_data[3] = (p2 == OMX_IndexParamPortDefinition) ?
   1881                                                 frame_data[1] : pThis->drv_ctx.video_resolution.frame_width;
   1882                                             frame_data[4] = pThis->dpb_bit_depth;
   1883                                             frame_data[5] = pThis->m_color_space;
   1884                                             frame_data[6] = pThis->m_dither_config;
   1885 
   1886                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1887                                                     OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data );
   1888                                         } else {
   1889                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1890                                         }
   1891                                         break;
   1892 
   1893                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1894                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1895                                         if (pThis->m_cb.EventHandler) {
   1896                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1897                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1898                                         } else {
   1899                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1900                                         }
   1901                                         pThis->prev_ts = LLONG_MAX;
   1902                                         pThis->rst_prev_ts = true;
   1903                                         break;
   1904 
   1905                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1906                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1907                                         pThis->omx_report_error();
   1908                                         break;
   1909 
   1910                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1911                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
   1912                                         pThis->omx_report_unsupported_setting();
   1913                                         break;
   1914 
   1915                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
   1916                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
   1917                                         pThis->omx_report_hw_overload();
   1918                                         break;
   1919 
   1920                 default:
   1921                                         break;
   1922             }
   1923         }
   1924         pthread_mutex_lock(&pThis->m_lock);
   1925         qsize = pThis->m_cmd_q.m_size;
   1926         if (pThis->m_state != OMX_StatePause)
   1927             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1928         pthread_mutex_unlock(&pThis->m_lock);
   1929     } while (qsize>0);
   1930 
   1931 }
   1932 
   1933 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1934 {
   1935     int format_changed = 0;
   1936     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
   1937             (width != (int)drv_ctx.video_resolution.frame_width)) {
   1938         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
   1939                 width, drv_ctx.video_resolution.frame_width,
   1940                 height,drv_ctx.video_resolution.frame_height);
   1941         format_changed = 1;
   1942     }
   1943     drv_ctx.video_resolution.frame_height = height;
   1944     drv_ctx.video_resolution.frame_width = width;
   1945     drv_ctx.video_resolution.scan_lines = scan_lines;
   1946     drv_ctx.video_resolution.stride = stride;
   1947 
   1948     if (!is_down_scalar_enabled) {
   1949         rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft;
   1950         rectangle.nTop = m_extradata_info.output_crop_rect.nTop;
   1951         rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth;
   1952         rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight;
   1953     }
   1954     return format_changed;
   1955 }
   1956 
   1957 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1958 {
   1959     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1960                 OMX_MAX_STRINGNAME_SIZE) &&
   1961             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1962         m_decoder_capability.max_width = 1280;
   1963         m_decoder_capability.max_height = 720;
   1964         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1965     }
   1966 
   1967     if ((drv_ctx.video_resolution.frame_width *
   1968                 drv_ctx.video_resolution.frame_height >
   1969                 m_decoder_capability.max_width *
   1970                 m_decoder_capability.max_height) ||
   1971             (drv_ctx.video_resolution.frame_width*
   1972              drv_ctx.video_resolution.frame_height <
   1973              m_decoder_capability.min_width *
   1974              m_decoder_capability.min_height)) {
   1975         DEBUG_PRINT_ERROR(
   1976                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1977                 drv_ctx.video_resolution.frame_width,
   1978                 drv_ctx.video_resolution.frame_height,
   1979                 m_decoder_capability.min_width,
   1980                 m_decoder_capability.min_height,
   1981                 m_decoder_capability.max_width,
   1982                 m_decoder_capability.max_height);
   1983         return OMX_ErrorUnsupportedSetting;
   1984     }
   1985     DEBUG_PRINT_HIGH("video session supported");
   1986     return OMX_ErrorNone;
   1987 }
   1988 
   1989 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
   1990 {
   1991     if (m_debug.in_buffer_log && !m_debug.infile) {
   1992         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   1993            snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v",
   1994                    m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1995         } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   1996                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc,
   1997                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1998         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   1999                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263",
   2000                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2001         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
   2002                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   2003                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
   2004                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2005         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   2006                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
   2007                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2008         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   2009                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   2010                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2011         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
   2012                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   2013                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2014         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   2015                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   2016                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2017         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2018                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   2019                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2020         } else {
   2021                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx",
   2022                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2023         }
   2024         m_debug.infile = fopen (m_debug.infile_name, "ab");
   2025         if (!m_debug.infile) {
   2026             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   2027             m_debug.infile_name[0] = '\0';
   2028             return -1;
   2029         }
   2030         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   2031                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2032             struct ivf_file_header {
   2033                 OMX_U8 signature[4]; //='DKIF';
   2034                 OMX_U8 version         ; //= 0;
   2035                 OMX_U8 headersize      ; //= 32;
   2036                 OMX_U32 FourCC;
   2037                 OMX_U8 width;
   2038                 OMX_U8 height;
   2039                 OMX_U32 rate;
   2040                 OMX_U32 scale;
   2041                 OMX_U32 length;
   2042                 OMX_U8 unused[4];
   2043             } file_header;
   2044 
   2045             memset((void *)&file_header,0,sizeof(file_header));
   2046             file_header.signature[0] = 'D';
   2047             file_header.signature[1] = 'K';
   2048             file_header.signature[2] = 'I';
   2049             file_header.signature[3] = 'F';
   2050             file_header.version = 0;
   2051             file_header.headersize = 32;
   2052             switch (drv_ctx.decoder_format) {
   2053                 case VDEC_CODECTYPE_VP8:
   2054                     file_header.FourCC = 0x30385056;
   2055                     break;
   2056                 case VDEC_CODECTYPE_VP9:
   2057                     file_header.FourCC = 0x30395056;
   2058                     break;
   2059                 default:
   2060                     DEBUG_PRINT_ERROR("unsupported format for VP8/VP9");
   2061                     break;
   2062             }
   2063             fwrite((const char *)&file_header,
   2064                     sizeof(file_header),1,m_debug.infile);
   2065          }
   2066     }
   2067     if (m_debug.infile && buffer_addr && buffer_len) {
   2068         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   2069                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2070             struct vpx_ivf_frame_header {
   2071                 OMX_U32 framesize;
   2072                 OMX_U32 timestamp_lo;
   2073                 OMX_U32 timestamp_hi;
   2074             } vpx_frame_header;
   2075             vpx_frame_header.framesize = buffer_len;
   2076             /* Currently FW doesn't use timestamp values */
   2077             vpx_frame_header.timestamp_lo = 0;
   2078             vpx_frame_header.timestamp_hi = 0;
   2079             fwrite((const char *)&vpx_frame_header,
   2080                     sizeof(vpx_frame_header),1,m_debug.infile);
   2081         }
   2082         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
   2083     }
   2084     return 0;
   2085 }
   2086 
   2087 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
   2088     int buf_index = 0;
   2089     char *temp = NULL;
   2090 
   2091     if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
   2092         return 0;
   2093 
   2094     if (m_debug.out_buffer_log && !m_debug.outfile) {
   2095         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv",
   2096                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2097         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
   2098         if (!m_debug.outfile) {
   2099             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
   2100             m_debug.outfile_name[0] = '\0';
   2101             return -1;
   2102         }
   2103     }
   2104 
   2105     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) {
   2106         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
   2107                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2108         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
   2109                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2110         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
   2111         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
   2112         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
   2113             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
   2114             m_debug.out_ymetafile_name[0] = '\0';
   2115             m_debug.out_uvmetafile_name[0] = '\0';
   2116             return -1;
   2117         }
   2118     }
   2119 
   2120     buf_index = buffer - m_out_mem_ptr;
   2121     temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   2122 
   2123     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
   2124             drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   2125         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
   2126             drv_ctx.video_resolution.frame_width,
   2127             drv_ctx.video_resolution.frame_height);
   2128 
   2129         if (m_debug.outfile)
   2130             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
   2131 
   2132         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
   2133             unsigned int width = 0, height = 0;
   2134             unsigned int y_plane, y_meta_plane;
   2135             int y_stride = 0, y_sclines = 0;
   2136             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
   2137             int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC;
   2138             int i;
   2139             int bytes_written = 0;
   2140 
   2141             width = drv_ctx.video_resolution.frame_width;
   2142             height = drv_ctx.video_resolution.frame_height;
   2143             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
   2144             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
   2145             y_stride = VENUS_Y_STRIDE(color_fmt, width);
   2146             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
   2147             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
   2148             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
   2149 
   2150             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
   2151             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
   2152 
   2153             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   2154             for (i = 0; i < y_meta_scanlines; i++) {
   2155                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
   2156                  temp += y_meta_stride;
   2157             }
   2158 
   2159             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
   2160             for(i = 0; i < uv_meta_scanlines; i++) {
   2161                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
   2162                 temp += uv_meta_stride;
   2163             }
   2164         }
   2165     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   2166         int stride = drv_ctx.video_resolution.stride;
   2167         int scanlines = drv_ctx.video_resolution.scan_lines;
   2168         if (m_smoothstreaming_mode) {
   2169             stride = drv_ctx.video_resolution.frame_width;
   2170             scanlines = drv_ctx.video_resolution.frame_height;
   2171             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
   2172             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
   2173         }
   2174         unsigned i;
   2175         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
   2176             drv_ctx.video_resolution.frame_width,
   2177             drv_ctx.video_resolution.frame_height, stride, scanlines);
   2178         int bytes_written = 0;
   2179         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   2180              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   2181              temp += stride;
   2182         }
   2183         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   2184         int stride_c = stride;
   2185         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   2186             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   2187             temp += stride_c;
   2188         }
   2189     }
   2190     return 0;
   2191 }
   2192 
   2193 /* ======================================================================
   2194    FUNCTION
   2195    omx_vdec::ComponentInit
   2196 
   2197    DESCRIPTION
   2198    Initialize the component.
   2199 
   2200    PARAMETERS
   2201    ctxt -- Context information related to the self.
   2202    id   -- Event identifier. This could be any of the following:
   2203    1. Command completion event
   2204    2. Buffer done callback event
   2205    3. Frame done callback event
   2206 
   2207    RETURN VALUE
   2208    None.
   2209 
   2210    ========================================================================== */
   2211 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   2212 {
   2213 
   2214     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2215     struct v4l2_fmtdesc fdesc;
   2216     struct v4l2_format fmt;
   2217     struct v4l2_requestbuffers bufreq;
   2218     struct v4l2_control control;
   2219     struct v4l2_frmsizeenum frmsize;
   2220     unsigned int   alignment = 0,buffer_size = 0;
   2221     int fds[2];
   2222     int r,ret=0;
   2223     bool codec_ambiguous = false;
   2224     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
   2225     char property_value[PROPERTY_VALUE_MAX] = {0};
   2226     FILE *soc_file = NULL;
   2227     char buffer[10];
   2228 
   2229 #ifdef _ANDROID_
   2230     char platform_name[PROPERTY_VALUE_MAX];
   2231     property_get("ro.board.platform", platform_name, "0");
   2232     if (!strncmp(platform_name, "msm8610", 7)) {
   2233         device_name = (OMX_STRING)"/dev/video/q6_dec";
   2234         is_q6_platform = true;
   2235         maxSmoothStreamingWidth = 1280;
   2236         maxSmoothStreamingHeight = 720;
   2237     }
   2238 #endif
   2239 
   2240     is_thulium_v1 = false;
   2241     soc_file = fopen("/sys/devices/soc0/soc_id", "r");
   2242     if (soc_file) {
   2243         fread(buffer, 1, 4, soc_file);
   2244         fclose(soc_file);
   2245         if (atoi(buffer) == 246) {
   2246             soc_file = fopen("/sys/devices/soc0/revision", "r");
   2247             if (soc_file) {
   2248                 fread(buffer, 1, 4, soc_file);
   2249                 fclose(soc_file);
   2250                 if (atoi(buffer) == 1) {
   2251                     is_thulium_v1 = true;
   2252                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
   2253                 }
   2254             }
   2255         }
   2256     }
   2257 
   2258 #ifdef _ANDROID_
   2259     /*
   2260      * turn off frame parsing for Android by default.
   2261      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
   2262      */
   2263     arbitrary_bytes = false;
   2264     property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   2265     if (atoi(property_value)) {
   2266         DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
   2267         arbitrary_bytes = true;
   2268     }
   2269 #endif
   2270 
   2271     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
   2272                 OMX_MAX_STRINGNAME_SIZE)) {
   2273         secure_mode = true;
   2274         arbitrary_bytes = false;
   2275         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   2276     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
   2277                 OMX_MAX_STRINGNAME_SIZE)) {
   2278         secure_mode = true;
   2279         arbitrary_bytes = false;
   2280         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
   2281     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
   2282                 OMX_MAX_STRINGNAME_SIZE)) {
   2283         secure_mode = true;
   2284         arbitrary_bytes = false;
   2285         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
   2286     } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
   2287                 OMX_MAX_STRINGNAME_SIZE)) {
   2288         secure_mode = true;
   2289         arbitrary_bytes = false;
   2290         role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
   2291     } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
   2292                 OMX_MAX_STRINGNAME_SIZE)) {
   2293         secure_mode = true;
   2294         arbitrary_bytes = false;
   2295         role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
   2296     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
   2297                 OMX_MAX_STRINGNAME_SIZE)) {
   2298         secure_mode = true;
   2299         arbitrary_bytes = false;
   2300         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
   2301     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
   2302                 OMX_MAX_STRINGNAME_SIZE)) {
   2303         secure_mode = true;
   2304         arbitrary_bytes = false;
   2305         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
   2306     }
   2307     else if (!strncmp(role, "OMX.qcom.video.decoder.vp8.secure",
   2308                 OMX_MAX_STRINGNAME_SIZE)) {
   2309         secure_mode = true;
   2310         arbitrary_bytes = false;
   2311         role = (OMX_STRING)"OMX.qcom.video.decoder.vp8";
   2312     }
   2313 
   2314     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   2315 
   2316     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
   2317 
   2318     if (drv_ctx.video_driver_fd < 0) {
   2319         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
   2320         return OMX_ErrorInsufficientResources;
   2321     }
   2322     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   2323     drv_ctx.frame_rate.fps_denominator = 1;
   2324     operating_frame_rate = DEFAULT_FPS;
   2325     m_poll_efd = eventfd(0, 0);
   2326     if (m_poll_efd < 0) {
   2327         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
   2328         return OMX_ErrorInsufficientResources;
   2329     }
   2330     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   2331     if (!ret) {
   2332         async_thread_created = true;
   2333         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   2334     }
   2335     if (ret) {
   2336         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
   2337         async_thread_created = false;
   2338         return OMX_ErrorInsufficientResources;
   2339     }
   2340 
   2341 #ifdef OUTPUT_EXTRADATA_LOG
   2342     outputExtradataFile = fopen (output_extradata_filename, "ab");
   2343 #endif
   2344 
   2345     // Copy the role information which provides the decoder kind
   2346     strlcpy(drv_ctx.kind,role,128);
   2347 
   2348     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   2349                 OMX_MAX_STRINGNAME_SIZE)) {
   2350         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   2351                 OMX_MAX_STRINGNAME_SIZE);
   2352         drv_ctx.timestamp_adjust = true;
   2353         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   2354         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   2355         output_capability=V4L2_PIX_FMT_MPEG4;
   2356         /*Initialize Start Code for MPEG4*/
   2357         codec_type_parse = CODEC_TYPE_MPEG4;
   2358         m_frame_parser.init_start_codes(codec_type_parse);
   2359     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   2360                 OMX_MAX_STRINGNAME_SIZE)) {
   2361         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   2362                 OMX_MAX_STRINGNAME_SIZE);
   2363         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   2364         output_capability = V4L2_PIX_FMT_MPEG2;
   2365         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   2366         /*Initialize Start Code for MPEG2*/
   2367         codec_type_parse = CODEC_TYPE_MPEG2;
   2368         m_frame_parser.init_start_codes(codec_type_parse);
   2369     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   2370                 OMX_MAX_STRINGNAME_SIZE)) {
   2371         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   2372         DEBUG_PRINT_LOW("H263 Decoder selected");
   2373         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   2374         eCompressionFormat = OMX_VIDEO_CodingH263;
   2375         output_capability = V4L2_PIX_FMT_H263;
   2376         codec_type_parse = CODEC_TYPE_H263;
   2377         m_frame_parser.init_start_codes(codec_type_parse);
   2378     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   2379                 OMX_MAX_STRINGNAME_SIZE)) {
   2380         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2381         DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
   2382         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   2383         output_capability = V4L2_PIX_FMT_DIVX_311;
   2384         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2385         codec_type_parse = CODEC_TYPE_DIVX;
   2386         m_frame_parser.init_start_codes(codec_type_parse);
   2387 
   2388     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   2389                 OMX_MAX_STRINGNAME_SIZE)) {
   2390         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2391         DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
   2392         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   2393         output_capability = V4L2_PIX_FMT_DIVX;
   2394         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2395         codec_type_parse = CODEC_TYPE_DIVX;
   2396         codec_ambiguous = true;
   2397         m_frame_parser.init_start_codes(codec_type_parse);
   2398 
   2399     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   2400                 OMX_MAX_STRINGNAME_SIZE)) {
   2401         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2402         DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
   2403         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   2404         output_capability = V4L2_PIX_FMT_DIVX;
   2405         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2406         codec_type_parse = CODEC_TYPE_DIVX;
   2407         codec_ambiguous = true;
   2408         m_frame_parser.init_start_codes(codec_type_parse);
   2409 
   2410     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   2411                 OMX_MAX_STRINGNAME_SIZE)) {
   2412         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   2413         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   2414         output_capability=V4L2_PIX_FMT_H264;
   2415         eCompressionFormat = OMX_VIDEO_CodingAVC;
   2416         codec_type_parse = CODEC_TYPE_H264;
   2417         m_frame_parser.init_start_codes(codec_type_parse);
   2418         m_frame_parser.init_nal_length(nal_length);
   2419         if (is_thulium_v1) {
   2420             arbitrary_bytes = true;
   2421             DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264");
   2422         }
   2423     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
   2424                 OMX_MAX_STRINGNAME_SIZE)) {
   2425         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   2426         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
   2427         output_capability = V4L2_PIX_FMT_H264_MVC;
   2428         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
   2429         codec_type_parse = CODEC_TYPE_H264;
   2430         m_frame_parser.init_start_codes(codec_type_parse);
   2431         m_frame_parser.init_nal_length(nal_length);
   2432     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
   2433                 OMX_MAX_STRINGNAME_SIZE)) {
   2434         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
   2435         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
   2436         output_capability = V4L2_PIX_FMT_HEVC;
   2437         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
   2438         codec_type_parse = CODEC_TYPE_HEVC;
   2439         m_frame_parser.init_start_codes(codec_type_parse);
   2440         m_frame_parser.init_nal_length(nal_length);
   2441     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   2442                 OMX_MAX_STRINGNAME_SIZE)) {
   2443         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2444         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   2445         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2446         codec_type_parse = CODEC_TYPE_VC1;
   2447         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   2448         m_frame_parser.init_start_codes(codec_type_parse);
   2449     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   2450                 OMX_MAX_STRINGNAME_SIZE)) {
   2451         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2452         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   2453         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2454         codec_type_parse = CODEC_TYPE_VC1;
   2455         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   2456         m_frame_parser.init_start_codes(codec_type_parse);
   2457     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   2458                 OMX_MAX_STRINGNAME_SIZE)) {
   2459         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   2460         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
   2461         output_capability = V4L2_PIX_FMT_VP8;
   2462         eCompressionFormat = OMX_VIDEO_CodingVP8;
   2463         codec_type_parse = CODEC_TYPE_VP8;
   2464         arbitrary_bytes = false;
   2465     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
   2466                 OMX_MAX_STRINGNAME_SIZE)) {
   2467         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   2468         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
   2469         output_capability = V4L2_PIX_FMT_VP9;
   2470         eCompressionFormat = OMX_VIDEO_CodingVP9;
   2471         codec_type_parse = CODEC_TYPE_VP9;
   2472         arbitrary_bytes = false;
   2473     } else {
   2474         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
   2475         eRet = OMX_ErrorInvalidComponentName;
   2476     }
   2477 
   2478     if (eRet == OMX_ErrorNone) {
   2479         OMX_COLOR_FORMATTYPE dest_color_format;
   2480         if (m_disable_ubwc_mode) {
   2481             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   2482         } else {
   2483             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   2484         }
   2485         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
   2486             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2487                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   2488         else
   2489             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2490                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2491         if (!client_buffers.set_color_format(dest_color_format)) {
   2492             DEBUG_PRINT_ERROR("Setting color format failed");
   2493             eRet = OMX_ErrorInsufficientResources;
   2494         }
   2495 
   2496         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
   2497         m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
   2498 
   2499         if (m_disable_ubwc_mode) {
   2500             capture_capability = V4L2_PIX_FMT_NV12;
   2501         } else {
   2502             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   2503         }
   2504 
   2505         struct v4l2_capability cap;
   2506         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   2507         if (ret) {
   2508             DEBUG_PRINT_ERROR("Failed to query capabilities");
   2509             /*TODO: How to handle this case */
   2510         } else {
   2511             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   2512                 " version = %d, capabilities = %x", cap.driver, cap.card,
   2513                 cap.bus_info, cap.version, cap.capabilities);
   2514         }
   2515         ret=0;
   2516         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2517         fdesc.index=0;
   2518         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2519             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2520                     fdesc.pixelformat, fdesc.flags);
   2521             fdesc.index++;
   2522         }
   2523         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2524         fdesc.index=0;
   2525         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2526 
   2527             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2528                     fdesc.pixelformat, fdesc.flags);
   2529             fdesc.index++;
   2530         }
   2531         m_extradata_info.output_crop_rect.nLeft = 0;
   2532         m_extradata_info.output_crop_rect.nTop = 0;
   2533         m_extradata_info.output_crop_rect.nWidth = 320;
   2534         m_extradata_info.output_crop_rect.nHeight = 240;
   2535         update_resolution(320, 240, 320, 240);
   2536 
   2537         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2538         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2539         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2540         fmt.fmt.pix_mp.pixelformat = output_capability;
   2541         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2542         if (ret) {
   2543             /*TODO: How to handle this case */
   2544             DEBUG_PRINT_ERROR("Failed to set format on output port");
   2545             return OMX_ErrorInsufficientResources;
   2546         }
   2547         DEBUG_PRINT_HIGH("Set Format was successful");
   2548         if (codec_ambiguous) {
   2549             if (output_capability == V4L2_PIX_FMT_DIVX) {
   2550                 struct v4l2_control divx_ctrl;
   2551 
   2552                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   2553                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   2554                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   2555                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   2556                 } else {
   2557                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   2558                 }
   2559 
   2560                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   2561                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   2562                 if (ret) {
   2563                     DEBUG_PRINT_ERROR("Failed to set divx version");
   2564                 }
   2565             } else {
   2566                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   2567             }
   2568         }
   2569 
   2570         property_get("persist.vendor.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
   2571         m_conceal_color= atoi(property_value);
   2572         DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
   2573         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
   2574         control.value = m_conceal_color;
   2575         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2576         if (ret) {
   2577             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
   2578         }
   2579 
   2580         //Get the hardware capabilities
   2581         memset((void *)&frmsize,0,sizeof(frmsize));
   2582         frmsize.index = 0;
   2583         frmsize.pixel_format = output_capability;
   2584         ret = ioctl(drv_ctx.video_driver_fd,
   2585                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   2586         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   2587             DEBUG_PRINT_ERROR("Failed to get framesizes");
   2588             return OMX_ErrorHardware;
   2589         }
   2590 
   2591         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   2592             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   2593             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   2594             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   2595             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   2596         }
   2597 
   2598         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   2599         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2600         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2601         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2602         fmt.fmt.pix_mp.pixelformat = capture_capability;
   2603         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2604         if (ret) {
   2605             /*TODO: How to handle this case */
   2606             DEBUG_PRINT_ERROR("Failed to set format on capture port");
   2607         }
   2608         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
   2609         framesize.nWidth = drv_ctx.video_resolution.frame_width;
   2610         framesize.nHeight = drv_ctx.video_resolution.frame_height;
   2611 
   2612         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
   2613         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   2614         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   2615 
   2616         DEBUG_PRINT_HIGH("Set Format was successful");
   2617         if (secure_mode) {
   2618             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   2619             control.value = 1;
   2620             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
   2621             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   2622             if (ret) {
   2623                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
   2624                 return OMX_ErrorInsufficientResources;
   2625             }
   2626         }
   2627         if (output_capability == V4L2_PIX_FMT_H264_MVC) {
   2628             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
   2629             control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
   2630             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2631             if (ret) {
   2632                 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
   2633                 return OMX_ErrorInsufficientResources;
   2634             }
   2635         }
   2636 
   2637         if (is_thulium_v1) {
   2638             eRet = enable_smoothstreaming();
   2639             if (eRet != OMX_ErrorNone) {
   2640                DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver");
   2641                return eRet;
   2642             }
   2643         }
   2644 
   2645         /*Get the Buffer requirements for input and output ports*/
   2646         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2647         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2648 
   2649         if (secure_mode) {
   2650             drv_ctx.op_buf.alignment = SECURE_ALIGN;
   2651             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
   2652         } else {
   2653             drv_ctx.op_buf.alignment = SZ_4K;
   2654             drv_ctx.ip_buf.alignment = SZ_4K;
   2655         }
   2656 
   2657         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   2658         drv_ctx.extradata = 0;
   2659         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   2660         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   2661         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   2662         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2663         drv_ctx.idr_only_decoding = 0;
   2664 
   2665 #ifdef _ANDROID_
   2666         property_get("vendor.vidc.dec.enable.downscalar",property_value,"0");
   2667         if (atoi(property_value)) {
   2668             m_enable_downscalar =  atoi(property_value);
   2669             property_get("vendor.vidc.dec.downscalar_width",property_value,"0");
   2670             if (atoi(property_value)) {
   2671                 m_downscalar_width = atoi(property_value);
   2672             }
   2673             property_get("vendor.vidc.dec.downscalar_height",property_value,"0");
   2674             if (atoi(property_value)) {
   2675                 m_downscalar_height = atoi(property_value);
   2676             }
   2677 
   2678             if (m_downscalar_width < m_decoder_capability.min_width ||
   2679                 m_downscalar_height < m_decoder_capability.min_height) {
   2680                 m_downscalar_width = 0;
   2681                 m_downscalar_height = 0;
   2682             }
   2683 
   2684             DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n",
   2685                 m_downscalar_width, m_downscalar_height);
   2686         }
   2687         property_get("vendor.vidc.disable.split.mode",property_value,"0");
   2688         m_disable_split_mode = atoi(property_value);
   2689         DEBUG_PRINT_HIGH("split mode is %s", m_disable_split_mode ? "disabled" : "enabled");
   2690 #endif
   2691         m_state = OMX_StateLoaded;
   2692 #ifdef DEFAULT_EXTRADATA
   2693         enable_extradata(DEFAULT_EXTRADATA, true, true);
   2694 #endif
   2695         eRet = get_buffer_req(&drv_ctx.ip_buf);
   2696         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
   2697         get_buffer_req(&drv_ctx.op_buf);
   2698         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2699                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
   2700                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2701                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   2702                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   2703                     h264_scratch.nFilledLen = 0;
   2704                     h264_scratch.nOffset = 0;
   2705 
   2706                     if (h264_scratch.pBuffer == NULL) {
   2707                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
   2708                         return OMX_ErrorInsufficientResources;
   2709                     }
   2710         }
   2711         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2712             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2713             if (m_frame_parser.mutils == NULL) {
   2714                 m_frame_parser.mutils = new H264_Utils();
   2715                 if (m_frame_parser.mutils == NULL) {
   2716                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
   2717                     eRet = OMX_ErrorInsufficientResources;
   2718                 } else {
   2719                     m_frame_parser.mutils->initialize_frame_checking_environment();
   2720                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   2721                 }
   2722             }
   2723 
   2724             h264_parser = new h264_stream_parser();
   2725             if (!h264_parser) {
   2726                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   2727                 eRet = OMX_ErrorInsufficientResources;
   2728             }
   2729         }
   2730 
   2731         if (pipe(fds)) {
   2732             DEBUG_PRINT_ERROR("pipe creation failed");
   2733             eRet = OMX_ErrorInsufficientResources;
   2734         } else {
   2735             m_pipe_in = fds[0];
   2736             m_pipe_out = fds[1];
   2737             msg_thread_created = true;
   2738             r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
   2739 
   2740             if (r < 0) {
   2741                 DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
   2742                 msg_thread_created = false;
   2743                 eRet = OMX_ErrorInsufficientResources;
   2744             }
   2745         }
   2746     }
   2747 
   2748     {
   2749         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
   2750         init_vendor_extensions(*extStore);
   2751         mVendorExtensionStore.dumpExtensions((const char *)role);
   2752     }
   2753 
   2754     if (eRet != OMX_ErrorNone) {
   2755         DEBUG_PRINT_ERROR("Component Init Failed");
   2756     } else {
   2757         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
   2758                 drv_ctx.video_driver_fd);
   2759     }
   2760     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   2761     return eRet;
   2762 }
   2763 
   2764 /* ======================================================================
   2765    FUNCTION
   2766    omx_vdec::GetComponentVersion
   2767 
   2768    DESCRIPTION
   2769    Returns the component version.
   2770 
   2771    PARAMETERS
   2772    TBD.
   2773 
   2774    RETURN VALUE
   2775    OMX_ErrorNone.
   2776 
   2777    ========================================================================== */
   2778 OMX_ERRORTYPE  omx_vdec::get_component_version
   2779 (
   2780  OMX_IN OMX_HANDLETYPE hComp,
   2781  OMX_OUT OMX_STRING componentName,
   2782  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   2783  OMX_OUT OMX_VERSIONTYPE* specVersion,
   2784  OMX_OUT OMX_UUIDTYPE* componentUUID
   2785  )
   2786 {
   2787     (void) hComp;
   2788     (void) componentName;
   2789     (void) componentVersion;
   2790     (void) componentUUID;
   2791     if (m_state == OMX_StateInvalid) {
   2792         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
   2793         return OMX_ErrorInvalidState;
   2794     }
   2795     /* TBD -- Return the proper version */
   2796     if (specVersion) {
   2797         specVersion->nVersion = OMX_SPEC_VERSION;
   2798     }
   2799     return OMX_ErrorNone;
   2800 }
   2801 /* ======================================================================
   2802    FUNCTION
   2803    omx_vdec::SendCommand
   2804 
   2805    DESCRIPTION
   2806    Returns zero if all the buffers released..
   2807 
   2808    PARAMETERS
   2809    None.
   2810 
   2811    RETURN VALUE
   2812    true/false
   2813 
   2814    ========================================================================== */
   2815 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   2816         OMX_IN OMX_COMMANDTYPE cmd,
   2817         OMX_IN OMX_U32 param1,
   2818         OMX_IN OMX_PTR cmdData
   2819         )
   2820 {
   2821     (void) hComp;
   2822     (void) cmdData;
   2823     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
   2824     if (m_state == OMX_StateInvalid) {
   2825         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
   2826         return OMX_ErrorInvalidState;
   2827     }
   2828     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   2829             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   2830         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
   2831                 "to invalid port: %u", (unsigned int)param1);
   2832         return OMX_ErrorBadPortIndex;
   2833     }
   2834 
   2835     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   2836     sem_wait(&m_cmd_lock);
   2837     DEBUG_PRINT_LOW("send_command: Command Processed");
   2838     return OMX_ErrorNone;
   2839 }
   2840 
   2841 /* ======================================================================
   2842    FUNCTION
   2843    omx_vdec::SendCommand
   2844 
   2845    DESCRIPTION
   2846    Returns zero if all the buffers released..
   2847 
   2848    PARAMETERS
   2849    None.
   2850 
   2851    RETURN VALUE
   2852    true/false
   2853 
   2854    ========================================================================== */
   2855 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   2856         OMX_IN OMX_COMMANDTYPE cmd,
   2857         OMX_IN OMX_U32 param1,
   2858         OMX_IN OMX_PTR cmdData
   2859         )
   2860 {
   2861     (void) hComp;
   2862     (void) cmdData;
   2863     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2864     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   2865     int bFlag = 1,sem_posted = 0,ret=0;
   2866 
   2867     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
   2868     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
   2869             m_state, eState);
   2870 
   2871     if (cmd == OMX_CommandStateSet) {
   2872         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   2873         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   2874         /***************************/
   2875         /* Current State is Loaded */
   2876         /***************************/
   2877         if (m_state == OMX_StateLoaded) {
   2878             if (eState == OMX_StateIdle) {
   2879                 //if all buffers are allocated or all ports disabled
   2880                 if (allocate_done() ||
   2881                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   2882                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
   2883                 } else {
   2884                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
   2885                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   2886                     // Skip the event notification
   2887                     bFlag = 0;
   2888                 }
   2889             }
   2890             /* Requesting transition from Loaded to Loaded */
   2891             else if (eState == OMX_StateLoaded) {
   2892                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
   2893                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2894                         OMX_COMPONENT_GENERATE_EVENT);
   2895                 eRet = OMX_ErrorSameState;
   2896             }
   2897             /* Requesting transition from Loaded to WaitForResources */
   2898             else if (eState == OMX_StateWaitForResources) {
   2899                 /* Since error is None , we will post an event
   2900                    at the end of this function definition */
   2901                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
   2902             }
   2903             /* Requesting transition from Loaded to Executing */
   2904             else if (eState == OMX_StateExecuting) {
   2905                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
   2906                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2907                         OMX_COMPONENT_GENERATE_EVENT);
   2908                 eRet = OMX_ErrorIncorrectStateTransition;
   2909             }
   2910             /* Requesting transition from Loaded to Pause */
   2911             else if (eState == OMX_StatePause) {
   2912                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
   2913                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2914                         OMX_COMPONENT_GENERATE_EVENT);
   2915                 eRet = OMX_ErrorIncorrectStateTransition;
   2916             }
   2917             /* Requesting transition from Loaded to Invalid */
   2918             else if (eState == OMX_StateInvalid) {
   2919                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
   2920                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2921                 eRet = OMX_ErrorInvalidState;
   2922             } else {
   2923                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
   2924                         eState);
   2925                 eRet = OMX_ErrorBadParameter;
   2926             }
   2927         }
   2928 
   2929         /***************************/
   2930         /* Current State is IDLE */
   2931         /***************************/
   2932         else if (m_state == OMX_StateIdle) {
   2933             if (eState == OMX_StateLoaded) {
   2934                 if (release_done()) {
   2935                     /*
   2936                      * Since error is None , we will post an event at the end
   2937                      * of this function definition
   2938                      * Reset buffer requirements here to ensure setting buffer requirement
   2939                      * when component move to executing state from loaded state via Idle.
   2940                      */
   2941                     drv_ctx.op_buf.buffer_size = 0;
   2942                     drv_ctx.op_buf.actualcount = 0;
   2943                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
   2944                 } else {
   2945                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
   2946                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   2947                     // Skip the event notification
   2948                     bFlag = 0;
   2949                 }
   2950             }
   2951             /* Requesting transition from Idle to Executing */
   2952             else if (eState == OMX_StateExecuting) {
   2953                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2954                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   2955                 bFlag = 1;
   2956                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2957                 m_state=OMX_StateExecuting;
   2958                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
   2959             }
   2960             /* Requesting transition from Idle to Idle */
   2961             else if (eState == OMX_StateIdle) {
   2962                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
   2963                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2964                         OMX_COMPONENT_GENERATE_EVENT);
   2965                 eRet = OMX_ErrorSameState;
   2966             }
   2967             /* Requesting transition from Idle to WaitForResources */
   2968             else if (eState == OMX_StateWaitForResources) {
   2969                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
   2970                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2971                         OMX_COMPONENT_GENERATE_EVENT);
   2972                 eRet = OMX_ErrorIncorrectStateTransition;
   2973             }
   2974             /* Requesting transition from Idle to Pause */
   2975             else if (eState == OMX_StatePause) {
   2976                 /*To pause the Video core we need to start the driver*/
   2977                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   2978                       NULL) < */0) {
   2979                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
   2980                     omx_report_error ();
   2981                     eRet = OMX_ErrorHardware;
   2982                 } else {
   2983                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   2984                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
   2985                     bFlag = 0;
   2986                 }
   2987             }
   2988             /* Requesting transition from Idle to Invalid */
   2989             else if (eState == OMX_StateInvalid) {
   2990                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
   2991                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2992                 eRet = OMX_ErrorInvalidState;
   2993             } else {
   2994                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
   2995                 eRet = OMX_ErrorBadParameter;
   2996             }
   2997         }
   2998 
   2999         /******************************/
   3000         /* Current State is Executing */
   3001         /******************************/
   3002         else if (m_state == OMX_StateExecuting) {
   3003             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
   3004             /* Requesting transition from Executing to Idle */
   3005             if (eState == OMX_StateIdle) {
   3006                 /* Since error is None , we will post an event
   3007                    at the end of this function definition
   3008                  */
   3009                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
   3010                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   3011                 if (!sem_posted) {
   3012                     sem_posted = 1;
   3013                     sem_post (&m_cmd_lock);
   3014                     execute_omx_flush(OMX_ALL);
   3015                 }
   3016                 bFlag = 0;
   3017             }
   3018             /* Requesting transition from Executing to Paused */
   3019             else if (eState == OMX_StatePause) {
   3020                 DEBUG_PRINT_LOW("PAUSE Command Issued");
   3021                 m_state = OMX_StatePause;
   3022                 bFlag = 1;
   3023             }
   3024             /* Requesting transition from Executing to Loaded */
   3025             else if (eState == OMX_StateLoaded) {
   3026                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
   3027                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3028                         OMX_COMPONENT_GENERATE_EVENT);
   3029                 eRet = OMX_ErrorIncorrectStateTransition;
   3030             }
   3031             /* Requesting transition from Executing to WaitForResources */
   3032             else if (eState == OMX_StateWaitForResources) {
   3033                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
   3034                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3035                         OMX_COMPONENT_GENERATE_EVENT);
   3036                 eRet = OMX_ErrorIncorrectStateTransition;
   3037             }
   3038             /* Requesting transition from Executing to Executing */
   3039             else if (eState == OMX_StateExecuting) {
   3040                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
   3041                 post_event(OMX_EventError,OMX_ErrorSameState,\
   3042                         OMX_COMPONENT_GENERATE_EVENT);
   3043                 eRet = OMX_ErrorSameState;
   3044             }
   3045             /* Requesting transition from Executing to Invalid */
   3046             else if (eState == OMX_StateInvalid) {
   3047                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
   3048                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3049                 eRet = OMX_ErrorInvalidState;
   3050             } else {
   3051                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
   3052                 eRet = OMX_ErrorBadParameter;
   3053             }
   3054         }
   3055         /***************************/
   3056         /* Current State is Pause  */
   3057         /***************************/
   3058         else if (m_state == OMX_StatePause) {
   3059             /* Requesting transition from Pause to Executing */
   3060             if (eState == OMX_StateExecuting) {
   3061                 DEBUG_PRINT_LOW("Pause --> Executing");
   3062                 m_state = OMX_StateExecuting;
   3063                 bFlag = 1;
   3064             }
   3065             /* Requesting transition from Pause to Idle */
   3066             else if (eState == OMX_StateIdle) {
   3067                 /* Since error is None , we will post an event
   3068                    at the end of this function definition */
   3069                 DEBUG_PRINT_LOW("Pause --> Idle");
   3070                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   3071                 if (!sem_posted) {
   3072                     sem_posted = 1;
   3073                     sem_post (&m_cmd_lock);
   3074                     execute_omx_flush(OMX_ALL);
   3075                 }
   3076                 bFlag = 0;
   3077             }
   3078             /* Requesting transition from Pause to loaded */
   3079             else if (eState == OMX_StateLoaded) {
   3080                 DEBUG_PRINT_ERROR("Pause --> loaded");
   3081                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3082                         OMX_COMPONENT_GENERATE_EVENT);
   3083                 eRet = OMX_ErrorIncorrectStateTransition;
   3084             }
   3085             /* Requesting transition from Pause to WaitForResources */
   3086             else if (eState == OMX_StateWaitForResources) {
   3087                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
   3088                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3089                         OMX_COMPONENT_GENERATE_EVENT);
   3090                 eRet = OMX_ErrorIncorrectStateTransition;
   3091             }
   3092             /* Requesting transition from Pause to Pause */
   3093             else if (eState == OMX_StatePause) {
   3094                 DEBUG_PRINT_ERROR("Pause --> Pause");
   3095                 post_event(OMX_EventError,OMX_ErrorSameState,\
   3096                         OMX_COMPONENT_GENERATE_EVENT);
   3097                 eRet = OMX_ErrorSameState;
   3098             }
   3099             /* Requesting transition from Pause to Invalid */
   3100             else if (eState == OMX_StateInvalid) {
   3101                 DEBUG_PRINT_ERROR("Pause --> Invalid");
   3102                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3103                 eRet = OMX_ErrorInvalidState;
   3104             } else {
   3105                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
   3106                 eRet = OMX_ErrorBadParameter;
   3107             }
   3108         }
   3109         /***************************/
   3110         /* Current State is WaitForResources  */
   3111         /***************************/
   3112         else if (m_state == OMX_StateWaitForResources) {
   3113             /* Requesting transition from WaitForResources to Loaded */
   3114             if (eState == OMX_StateLoaded) {
   3115                 /* Since error is None , we will post an event
   3116                    at the end of this function definition */
   3117                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
   3118             }
   3119             /* Requesting transition from WaitForResources to WaitForResources */
   3120             else if (eState == OMX_StateWaitForResources) {
   3121                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
   3122                 post_event(OMX_EventError,OMX_ErrorSameState,
   3123                         OMX_COMPONENT_GENERATE_EVENT);
   3124                 eRet = OMX_ErrorSameState;
   3125             }
   3126             /* Requesting transition from WaitForResources to Executing */
   3127             else if (eState == OMX_StateExecuting) {
   3128                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
   3129                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3130                         OMX_COMPONENT_GENERATE_EVENT);
   3131                 eRet = OMX_ErrorIncorrectStateTransition;
   3132             }
   3133             /* Requesting transition from WaitForResources to Pause */
   3134             else if (eState == OMX_StatePause) {
   3135                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
   3136                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3137                         OMX_COMPONENT_GENERATE_EVENT);
   3138                 eRet = OMX_ErrorIncorrectStateTransition;
   3139             }
   3140             /* Requesting transition from WaitForResources to Invalid */
   3141             else if (eState == OMX_StateInvalid) {
   3142                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
   3143                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3144                 eRet = OMX_ErrorInvalidState;
   3145             }
   3146             /* Requesting transition from WaitForResources to Loaded -
   3147                is NOT tested by Khronos TS */
   3148 
   3149         } else {
   3150             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
   3151             eRet = OMX_ErrorBadParameter;
   3152         }
   3153     }
   3154     /********************************/
   3155     /* Current State is Invalid */
   3156     /*******************************/
   3157     else if (m_state == OMX_StateInvalid) {
   3158         /* State Transition from Inavlid to any state */
   3159         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   3160                     || OMX_StateIdle || OMX_StateExecuting
   3161                     || OMX_StatePause || OMX_StateInvalid)) {
   3162             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
   3163             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   3164                     OMX_COMPONENT_GENERATE_EVENT);
   3165             eRet = OMX_ErrorInvalidState;
   3166         }
   3167     } else if (cmd == OMX_CommandFlush) {
   3168         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
   3169                 "with param1: %u", (unsigned int)param1);
   3170 #ifdef _MSM8974_
   3171         send_codec_config();
   3172 #endif
   3173         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
   3174                     param1 == OMX_ALL)) {
   3175             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
   3176                struct timespec ts;
   3177 
   3178                clock_gettime(CLOCK_REALTIME, &ts);
   3179                ts.tv_sec += 2;
   3180                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
   3181                        m_queued_codec_config_count);
   3182                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
   3183                if (sem_timedwait(&m_safe_flush, &ts)) {
   3184                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
   3185                }
   3186                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
   3187             }
   3188         }
   3189 
   3190         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   3191             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   3192         }
   3193         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   3194             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   3195         }
   3196         if (!sem_posted) {
   3197             sem_posted = 1;
   3198             DEBUG_PRINT_LOW("Set the Semaphore");
   3199             sem_post (&m_cmd_lock);
   3200             execute_omx_flush(param1);
   3201         }
   3202         bFlag = 0;
   3203     } else if ( cmd == OMX_CommandPortEnable) {
   3204         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
   3205                 "with param1: %u", (unsigned int)param1);
   3206         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3207             m_inp_bEnabled = OMX_TRUE;
   3208 
   3209             if ( (m_state == OMX_StateLoaded &&
   3210                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3211                     || allocate_input_done()) {
   3212                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   3213                         OMX_COMPONENT_GENERATE_EVENT);
   3214             } else {
   3215                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3216                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   3217                 // Skip the event notification
   3218                 bFlag = 0;
   3219             }
   3220         }
   3221         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3222             DEBUG_PRINT_LOW("Enable output Port command recieved");
   3223             m_out_bEnabled = OMX_TRUE;
   3224 
   3225             if ( (m_state == OMX_StateLoaded &&
   3226                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3227                     || (allocate_output_done())) {
   3228                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   3229                         OMX_COMPONENT_GENERATE_EVENT);
   3230 
   3231             } else {
   3232                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3233                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3234                 // Skip the event notification
   3235                 bFlag = 0;
   3236                 /* enable/disable downscaling if required */
   3237                 ret = decide_downscalar();
   3238                 if (ret) {
   3239                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
   3240                 }
   3241             }
   3242         }
   3243     } else if (cmd == OMX_CommandPortDisable) {
   3244         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
   3245                 "with param1: %u", (unsigned int)param1);
   3246         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3247             codec_config_flag = false;
   3248             m_inp_bEnabled = OMX_FALSE;
   3249             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3250                     && release_input_done()) {
   3251                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   3252                         OMX_COMPONENT_GENERATE_EVENT);
   3253             } else {
   3254                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3255                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3256                     if (!sem_posted) {
   3257                         sem_posted = 1;
   3258                         sem_post (&m_cmd_lock);
   3259                     }
   3260                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   3261                 }
   3262 
   3263                 // Skip the event notification
   3264                 bFlag = 0;
   3265             }
   3266         }
   3267         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3268             m_out_bEnabled = OMX_FALSE;
   3269             DEBUG_PRINT_LOW("Disable output Port command recieved");
   3270             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3271                     && release_output_done()) {
   3272                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   3273                         OMX_COMPONENT_GENERATE_EVENT);
   3274             } else {
   3275                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3276                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3277                     if (!sem_posted) {
   3278                         sem_posted = 1;
   3279                         sem_post (&m_cmd_lock);
   3280                     }
   3281                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   3282                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   3283                 }
   3284                 // Skip the event notification
   3285                 bFlag = 0;
   3286 
   3287             }
   3288         }
   3289     } else {
   3290         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
   3291         eRet = OMX_ErrorNotImplemented;
   3292     }
   3293     if (eRet == OMX_ErrorNone && bFlag) {
   3294         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   3295     }
   3296     if (!sem_posted) {
   3297         sem_post(&m_cmd_lock);
   3298     }
   3299 
   3300     return eRet;
   3301 }
   3302 
   3303 /* ======================================================================
   3304    FUNCTION
   3305    omx_vdec::ExecuteOmxFlush
   3306 
   3307    DESCRIPTION
   3308    Executes the OMX flush.
   3309 
   3310    PARAMETERS
   3311    flushtype - input flush(1)/output flush(0)/ both.
   3312 
   3313    RETURN VALUE
   3314    true/false
   3315 
   3316    ========================================================================== */
   3317 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   3318 {
   3319     bool bRet = false;
   3320     struct v4l2_plane plane;
   3321     struct v4l2_buffer v4l2_buf;
   3322     struct v4l2_decoder_cmd dec;
   3323     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
   3324     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   3325     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   3326 
   3327     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   3328 
   3329     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   3330         output_flush_progress = true;
   3331         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3332     } else {
   3333         /* XXX: The driver/hardware does not support flushing of individual ports
   3334          * in all states. So we pretty much need to flush both ports internally,
   3335          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   3336          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   3337          * we automatically omit sending the FLUSH done for the "opposite" port. */
   3338         input_flush_progress = true;
   3339         output_flush_progress = true;
   3340         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3341         request_perf_level(VIDC_TURBO);
   3342     }
   3343 
   3344     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   3345         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
   3346         bRet = false;
   3347     }
   3348 
   3349     return bRet;
   3350 }
   3351 /*=========================================================================
   3352 FUNCTION : execute_output_flush
   3353 
   3354 DESCRIPTION
   3355 Executes the OMX flush at OUTPUT PORT.
   3356 
   3357 PARAMETERS
   3358 None.
   3359 
   3360 RETURN VALUE
   3361 true/false
   3362 ==========================================================================*/
   3363 bool omx_vdec::execute_output_flush()
   3364 {
   3365     unsigned long p1 = 0; // Parameter - 1
   3366     unsigned long p2 = 0; // Parameter - 2
   3367     unsigned long ident = 0;
   3368     bool bRet = true;
   3369 
   3370     /*Generate FBD for all Buffers in the FTBq*/
   3371     pthread_mutex_lock(&m_lock);
   3372     DEBUG_PRINT_LOW("Initiate Output Flush");
   3373 
   3374     //reset last render TS
   3375     if(m_last_rendered_TS > 0) {
   3376         m_last_rendered_TS = 0;
   3377     }
   3378 
   3379     while (m_ftb_q.m_size) {
   3380         DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
   3381                 m_ftb_q.m_size,pending_output_buffers);
   3382         m_ftb_q.pop_entry(&p1,&p2,&ident);
   3383         DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
   3384         if (ident == m_fill_output_msg ) {
   3385             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
   3386         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   3387             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
   3388         }
   3389     }
   3390     pthread_mutex_unlock(&m_lock);
   3391     output_flush_progress = false;
   3392 
   3393     if (arbitrary_bytes) {
   3394         prev_ts = LLONG_MAX;
   3395         rst_prev_ts = true;
   3396     }
   3397     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   3398     return bRet;
   3399 }
   3400 /*=========================================================================
   3401 FUNCTION : execute_input_flush
   3402 
   3403 DESCRIPTION
   3404 Executes the OMX flush at INPUT PORT.
   3405 
   3406 PARAMETERS
   3407 None.
   3408 
   3409 RETURN VALUE
   3410 true/false
   3411 ==========================================================================*/
   3412 bool omx_vdec::execute_input_flush()
   3413 {
   3414     unsigned       i =0;
   3415     unsigned long p1 = 0; // Parameter - 1
   3416     unsigned long p2 = 0; // Parameter - 2
   3417     unsigned long ident = 0;
   3418     bool bRet = true;
   3419 
   3420     /*Generate EBD for all Buffers in the ETBq*/
   3421     DEBUG_PRINT_LOW("Initiate Input Flush");
   3422 
   3423     pthread_mutex_lock(&m_lock);
   3424     DEBUG_PRINT_LOW("Check if the Queue is empty");
   3425     while (m_etb_q.m_size) {
   3426         m_etb_q.pop_entry(&p1,&p2,&ident);
   3427 
   3428         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   3429             DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   3430             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   3431         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   3432             pending_input_buffers++;
   3433             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   3434             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   3435                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   3436             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   3437         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   3438             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   3439                     (OMX_BUFFERHEADERTYPE *)p1);
   3440             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   3441         }
   3442     }
   3443     time_stamp_dts.flush_timestamp();
   3444     /*Check if Heap Buffers are to be flushed*/
   3445     if (arbitrary_bytes && !(codec_config_flag)) {
   3446         DEBUG_PRINT_LOW("Reset all the variables before flusing");
   3447         h264_scratch.nFilledLen = 0;
   3448         nal_count = 0;
   3449         look_ahead_nal = false;
   3450         frame_count = 0;
   3451         h264_last_au_ts = LLONG_MAX;
   3452         h264_last_au_flags = 0;
   3453         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   3454         m_demux_entries = 0;
   3455         DEBUG_PRINT_LOW("Initialize parser");
   3456         if (m_frame_parser.mutils) {
   3457             m_frame_parser.mutils->initialize_frame_checking_environment();
   3458         }
   3459 
   3460         while (m_input_pending_q.m_size) {
   3461             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   3462             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   3463         }
   3464 
   3465         if (psource_frame) {
   3466             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   3467             psource_frame = NULL;
   3468         }
   3469 
   3470         if (pdest_frame) {
   3471             pdest_frame->nFilledLen = 0;
   3472             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
   3473                     (unsigned int)NULL);
   3474             pdest_frame = NULL;
   3475         }
   3476         m_frame_parser.flush();
   3477     } else if (codec_config_flag) {
   3478         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   3479                 "is not sent to the driver yet");
   3480     }
   3481     pthread_mutex_unlock(&m_lock);
   3482     input_flush_progress = false;
   3483     if (!arbitrary_bytes) {
   3484         prev_ts = LLONG_MAX;
   3485         rst_prev_ts = true;
   3486     }
   3487 #ifdef _ANDROID_
   3488     if (m_debug_timestamp) {
   3489         m_timestamp_list.reset_ts_list();
   3490     }
   3491 #endif
   3492     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   3493     return bRet;
   3494 }
   3495 
   3496 /*=========================================================================
   3497 FUNCTION : notify_flush_done
   3498 
   3499 DESCRIPTION
   3500 Notifies flush done to the OMX Client.
   3501 
   3502 PARAMETERS
   3503 ctxt -- Context information related to the self..
   3504 
   3505 RETURN VALUE
   3506 NONE
   3507 ==========================================================================*/
   3508 void omx_vdec::notify_flush_done(void *ctxt) {
   3509 
   3510     omx_vdec *pThis = (omx_vdec *) ctxt;
   3511 
   3512     if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
   3513         if (BITMASK_PRESENT(&pThis->m_flags,
   3514                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   3515             DEBUG_PRINT_LOW("Notify Output Flush done");
   3516             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   3517             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3518                 OMX_EventCmdComplete,OMX_CommandFlush,
   3519                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   3520         }
   3521 
   3522         if (BITMASK_PRESENT(&pThis->m_flags,
   3523                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
   3524             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   3525             DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
   3526             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3527                     OMX_EventCmdComplete,OMX_CommandFlush,
   3528                     OMX_CORE_INPUT_PORT_INDEX,NULL );
   3529         }
   3530     }
   3531 }
   3532 
   3533 /* ======================================================================
   3534    FUNCTION
   3535    omx_vdec::SendCommandEvent
   3536 
   3537    DESCRIPTION
   3538    Send the event to decoder pipe.  This is needed to generate the callbacks
   3539    in decoder thread context.
   3540 
   3541    PARAMETERS
   3542    None.
   3543 
   3544    RETURN VALUE
   3545    true/false
   3546 
   3547    ========================================================================== */
   3548 bool omx_vdec::post_event(unsigned long p1,
   3549         unsigned long p2,
   3550         unsigned long id)
   3551 {
   3552     bool bRet = false;
   3553 
   3554     /* Just drop messages typically generated by hardware (w/o client request),
   3555      * if we've reported an error to client. */
   3556     if (m_error_propogated) {
   3557         switch (id) {
   3558             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   3559             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   3560                 DEBUG_PRINT_ERROR("Dropping message %lx "
   3561                         "since client expected to be in error state", id);
   3562                 return false;
   3563             default:
   3564                 /* whatever */
   3565                 break;
   3566         }
   3567     }
   3568 
   3569     pthread_mutex_lock(&m_lock);
   3570 
   3571     if (id == m_fill_output_msg ||
   3572             id == OMX_COMPONENT_GENERATE_FBD ||
   3573             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
   3574             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
   3575         m_ftb_q.insert_entry(p1,p2,id);
   3576     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   3577             id == OMX_COMPONENT_GENERATE_EBD ||
   3578             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
   3579             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
   3580         m_etb_q.insert_entry(p1,p2,id);
   3581     } else {
   3582         m_cmd_q.insert_entry(p1,p2,id);
   3583     }
   3584 
   3585     bRet = true;
   3586     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   3587     post_message(this, id);
   3588 
   3589     pthread_mutex_unlock(&m_lock);
   3590 
   3591     return bRet;
   3592 }
   3593 
   3594 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   3595 {
   3596     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3597     if (!profileLevelType)
   3598         return OMX_ErrorBadParameter;
   3599 
   3600     if (profileLevelType->nPortIndex == 0) {
   3601         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3602             profileLevelType->eLevel = OMX_VIDEO_AVCLevel51;
   3603             if (profileLevelType->nProfileIndex == 0) {
   3604                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3605             } else if (profileLevelType->nProfileIndex == 1) {
   3606                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   3607             } else if (profileLevelType->nProfileIndex == 2) {
   3608                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   3609             } else if (profileLevelType->nProfileIndex == 3) {
   3610                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
   3611             } else if (profileLevelType->nProfileIndex == 4) {
   3612                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   3613             } else if (profileLevelType->nProfileIndex == 5) {
   3614                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
   3615             } else if (profileLevelType->nProfileIndex == 6) {
   3616                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
   3617             } else {
   3618                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3619                         (unsigned int)profileLevelType->nProfileIndex);
   3620                 eRet = OMX_ErrorNoMore;
   3621             }
   3622         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3623             if (profileLevelType->nProfileIndex == 0) {
   3624                 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
   3625                 profileLevelType->eLevel   = QOMX_VIDEO_MVCLevel51;
   3626             } else {
   3627                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3628                                 (unsigned int)profileLevelType->nProfileIndex);
   3629                 eRet = OMX_ErrorNoMore;
   3630             }
   3631         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3632             if (profileLevelType->nProfileIndex == 0) {
   3633                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
   3634                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3635             } else if (profileLevelType->nProfileIndex == 1) {
   3636                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
   3637                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3638             } else if (profileLevelType->nProfileIndex == 2) {
   3639                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
   3640                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3641             } else {
   3642                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3643                         (unsigned int)profileLevelType->nProfileIndex);
   3644                 eRet = OMX_ErrorNoMore;
   3645             }
   3646         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   3647             if (profileLevelType->nProfileIndex == 0) {
   3648                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   3649                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   3650             } else {
   3651                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3652                                 (unsigned int)profileLevelType->nProfileIndex);
   3653                 eRet = OMX_ErrorNoMore;
   3654             }
   3655         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3656             if (profileLevelType->nProfileIndex == 0) {
   3657                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   3658                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3659             } else if (profileLevelType->nProfileIndex == 1) {
   3660                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   3661                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3662             } else {
   3663                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3664                                 (unsigned int)profileLevelType->nProfileIndex);
   3665                 eRet = OMX_ErrorNoMore;
   3666             }
   3667         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3668                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   3669             eRet = OMX_ErrorNoMore;
   3670         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3671             if (profileLevelType->nProfileIndex == 0) {
   3672                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   3673                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3674             } else if (profileLevelType->nProfileIndex == 1) {
   3675                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   3676                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3677             } else {
   3678                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3679                                 (unsigned int)profileLevelType->nProfileIndex);
   3680                 eRet = OMX_ErrorNoMore;
   3681             }
   3682         } else {
   3683             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
   3684             eRet = OMX_ErrorNoMore;
   3685         }
   3686     } else {
   3687         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
   3688                           (unsigned int)profileLevelType->nPortIndex);
   3689         eRet = OMX_ErrorBadPortIndex;
   3690     }
   3691     return eRet;
   3692 }
   3693 
   3694 /* ======================================================================
   3695    FUNCTION
   3696    omx_vdec::GetParameter
   3697 
   3698    DESCRIPTION
   3699    OMX Get Parameter method implementation
   3700 
   3701    PARAMETERS
   3702    <TBD>.
   3703 
   3704    RETURN VALUE
   3705    Error None if successful.
   3706 
   3707    ========================================================================== */
   3708 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3709         OMX_IN OMX_INDEXTYPE paramIndex,
   3710         OMX_INOUT OMX_PTR     paramData)
   3711 {
   3712     (void) hComp;
   3713     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3714 
   3715     DEBUG_PRINT_LOW("get_parameter:");
   3716     if (m_state == OMX_StateInvalid) {
   3717         DEBUG_PRINT_ERROR("Get Param in Invalid State");
   3718         return OMX_ErrorInvalidState;
   3719     }
   3720     if (paramData == NULL) {
   3721         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
   3722         return OMX_ErrorBadParameter;
   3723     }
   3724     switch ((unsigned long)paramIndex) {
   3725         case OMX_IndexParamPortDefinition: {
   3726                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3727                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   3728                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3729                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   3730                                decide_dpb_buffer_mode(is_down_scalar_enabled);
   3731                                eRet = update_portdef(portDefn);
   3732                                if (eRet == OMX_ErrorNone)
   3733                                    m_port_def = *portDefn;
   3734                                break;
   3735                            }
   3736         case OMX_IndexParamVideoInit: {
   3737                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3738                               OMX_PORT_PARAM_TYPE *portParamType =
   3739                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3740                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   3741 
   3742                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3743                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3744                               portParamType->nPorts           = 2;
   3745                               portParamType->nStartPortNumber = 0;
   3746                               break;
   3747                           }
   3748         case OMX_IndexParamVideoPortFormat: {
   3749                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3750                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3751                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3752                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   3753 
   3754                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   3755                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3756 
   3757                                 if (0 == portFmt->nPortIndex) {
   3758                                     if (0 == portFmt->nIndex) {
   3759                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   3760                                         portFmt->eCompressionFormat = eCompressionFormat;
   3761                                     } else {
   3762                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3763                                                 " NoMore compression formats");
   3764                                         eRet =  OMX_ErrorNoMore;
   3765                                     }
   3766                                 } else if (1 == portFmt->nPortIndex) {
   3767                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   3768 
   3769                                     // Distinguish non-surface mode from normal playback use-case based on
   3770                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
   3771                                     // For non-android, use the default list
   3772                                     // Also use default format-list if FLEXIBLE YUV is supported,
   3773                                     // as the client negotiates the standard color-format if it needs to
   3774                                     bool useNonSurfaceMode = false;
   3775 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
   3776                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
   3777 #endif
   3778                                     if (is_thulium_v1) {
   3779                                         portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3780                                     } else {
   3781                                         portFmt->eColorFormat = useNonSurfaceMode ?
   3782                                             getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
   3783                                             getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3784                                     }
   3785 
   3786                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
   3787                                         eRet = OMX_ErrorNoMore;
   3788                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3789                                                 " NoMore Color formats");
   3790                                     }
   3791                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
   3792                                 } else {
   3793                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   3794                                             (int)portFmt->nPortIndex);
   3795                                     eRet = OMX_ErrorBadPortIndex;
   3796                                 }
   3797                                 break;
   3798                             }
   3799                             /*Component should support this port definition*/
   3800         case OMX_IndexParamAudioInit: {
   3801                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3802                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   3803                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3804                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   3805                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3806                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3807                               audioPortParamType->nPorts           = 0;
   3808                               audioPortParamType->nStartPortNumber = 0;
   3809                               break;
   3810                           }
   3811                           /*Component should support this port definition*/
   3812         case OMX_IndexParamImageInit: {
   3813                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3814                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   3815                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3816                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   3817                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3818                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3819                               imagePortParamType->nPorts           = 0;
   3820                               imagePortParamType->nStartPortNumber = 0;
   3821                               break;
   3822 
   3823                           }
   3824                           /*Component should support this port definition*/
   3825         case OMX_IndexParamOtherInit: {
   3826                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
   3827                                       paramIndex);
   3828                               eRet =OMX_ErrorUnsupportedIndex;
   3829                               break;
   3830                           }
   3831         case OMX_IndexParamStandardComponentRole: {
   3832                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   3833                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3834                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3835                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   3836                                   comp_role->nSize = sizeof(*comp_role);
   3837 
   3838                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
   3839                                           paramIndex);
   3840                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   3841                                           OMX_MAX_STRINGNAME_SIZE);
   3842                                   break;
   3843                               }
   3844                               /* Added for parameter test */
   3845         case OMX_IndexParamPriorityMgmt: {
   3846                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   3847                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   3848                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   3849                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   3850                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   3851                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
   3852 
   3853                              break;
   3854                          }
   3855                          /* Added for parameter test */
   3856         case OMX_IndexParamCompBufferSupplier: {
   3857                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   3858                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   3859                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3860                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   3861 
   3862                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
   3863                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   3864                                    if (0 == bufferSupplierType->nPortIndex)
   3865                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3866                                    else if (1 == bufferSupplierType->nPortIndex)
   3867                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3868                                    else
   3869                                        eRet = OMX_ErrorBadPortIndex;
   3870 
   3871 
   3872                                    break;
   3873                                }
   3874         case OMX_IndexParamVideoAvc: {
   3875                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
   3876                                      paramIndex);
   3877                              break;
   3878                          }
   3879         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3880                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
   3881                                      paramIndex);
   3882                              break;
   3883                          }
   3884         case OMX_IndexParamVideoH263: {
   3885                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   3886                                       paramIndex);
   3887                               break;
   3888                           }
   3889         case OMX_IndexParamVideoMpeg4: {
   3890                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   3891                                        paramIndex);
   3892                                break;
   3893                            }
   3894         case OMX_IndexParamVideoMpeg2: {
   3895                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   3896                                        paramIndex);
   3897                                break;
   3898                            }
   3899         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   3900                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3901                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
   3902                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   3903                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   3904                                         eRet = get_supported_profile_level(profileLevelType);
   3905                                         break;
   3906                                     }
   3907 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3908         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   3909                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
   3910                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   3911                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   3912                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3913 
   3914                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
   3915                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   3916                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   3917                                             } else {
   3918                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
   3919                                             }
   3920                                         } else {
   3921                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   3922                                             eRet = OMX_ErrorBadParameter;
   3923                                         }
   3924                                     }
   3925                                     break;
   3926 #endif
   3927 
   3928 #ifdef FLEXYUV_SUPPORTED
   3929         case OMX_QcomIndexFlexibleYUVDescription: {
   3930                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
   3931                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
   3932                 eRet = describeColorFormat(paramData);
   3933                 break;
   3934             }
   3935 #endif
   3936         case OMX_IndexParamVideoProfileLevelCurrent: {
   3937              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3938              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3939              struct v4l2_control profile_control, level_control;
   3940 
   3941              switch (drv_ctx.decoder_format) {
   3942                  case VDEC_CODECTYPE_H264:
   3943                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   3944                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   3945                      break;
   3946                  default:
   3947                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
   3948                      eRet = OMX_ErrorNotImplemented;
   3949                      break;
   3950              }
   3951 
   3952              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
   3953                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
   3954                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   3955                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   3956                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3957                         break;
   3958                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   3959                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
   3960                         break;
   3961                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   3962                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
   3963                         break;
   3964                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   3965                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
   3966                         break;
   3967                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   3968                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
   3969                         break;
   3970                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   3971                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
   3972                         break;
   3973                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   3974                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
   3975                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
   3976                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
   3977                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
   3978                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
   3979                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
   3980                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
   3981                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
   3982                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
   3983                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   3984                         eRet = OMX_ErrorUnsupportedIndex;
   3985                         break;
   3986                 }
   3987              } else {
   3988                  eRet = OMX_ErrorUnsupportedIndex;
   3989              }
   3990 
   3991 
   3992              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
   3993                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
   3994                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   3995                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
   3996                         break;
   3997                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   3998                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
   3999                         break;
   4000                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   4001                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
   4002                         break;
   4003                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   4004                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
   4005                         break;
   4006                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   4007                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
   4008                         break;
   4009                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   4010                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
   4011                         break;
   4012                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   4013                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
   4014                         break;
   4015                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   4016                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
   4017                         break;
   4018                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   4019                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
   4020                         break;
   4021                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   4022                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
   4023                         break;
   4024                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   4025                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
   4026                         break;
   4027                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   4028                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
   4029                         break;
   4030                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   4031                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
   4032                         break;
   4033                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   4034                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
   4035                         break;
   4036                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   4037                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
   4038                         break;
   4039                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   4040                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
   4041                         break;
   4042                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   4043                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
   4044                         break;
   4045                 }
   4046              } else {
   4047                  eRet = OMX_ErrorUnsupportedIndex;
   4048              }
   4049 
   4050              break;
   4051 
   4052          }
   4053         case OMX_QTIIndexParamVideoClientExtradata:
   4054         {
   4055             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
   4056             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
   4057             QOMX_EXTRADATA_ENABLE *pParam =
   4058                 (QOMX_EXTRADATA_ENABLE *)paramData;
   4059             if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   4060                 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE;
   4061                 eRet = OMX_ErrorNone;
   4062             } else {
   4063                 eRet = OMX_ErrorUnsupportedIndex;
   4064             }
   4065             break;
   4066         }
   4067         case OMX_QTIIndexParamDitherControl:
   4068         {
   4069             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
   4070             DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL");
   4071             QOMX_VIDEO_DITHER_CONTROL *pParam =
   4072                 (QOMX_VIDEO_DITHER_CONTROL *) paramData;
   4073             pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config;
   4074             eRet = OMX_ErrorNone;
   4075             break;
   4076         }
   4077         default: {
   4078                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
   4079                  eRet =OMX_ErrorUnsupportedIndex;
   4080              }
   4081 
   4082     }
   4083 
   4084     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
   4085             drv_ctx.video_resolution.frame_width,
   4086             drv_ctx.video_resolution.frame_height,
   4087             drv_ctx.video_resolution.stride,
   4088             drv_ctx.video_resolution.scan_lines);
   4089 
   4090     return eRet;
   4091 }
   4092 
   4093 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4094 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   4095 {
   4096     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   4097     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4098     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   4099 
   4100     if ((params == NULL) ||
   4101             (params->nativeBuffer == NULL) ||
   4102             (params->nativeBuffer->handle == NULL) ||
   4103             !m_enable_android_native_buffers)
   4104         return OMX_ErrorBadParameter;
   4105     m_use_android_native_buffers = OMX_TRUE;
   4106     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   4107     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   4108     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   4109         OMX_U8 *buffer = NULL;
   4110         if (!secure_mode) {
   4111             buffer = (OMX_U8*)mmap(0, handle->size,
   4112                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   4113             if (buffer == MAP_FAILED) {
   4114                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   4115                 return OMX_ErrorInsufficientResources;
   4116             }
   4117         }
   4118         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   4119     } else {
   4120         eRet = OMX_ErrorBadParameter;
   4121     }
   4122     return eRet;
   4123 }
   4124 #endif
   4125 
   4126 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
   4127     struct v4l2_control control;
   4128     struct v4l2_format fmt;
   4129     control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   4130     control.value = 1;
   4131     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   4132     if (rc < 0) {
   4133         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   4134         return OMX_ErrorHardware;
   4135     }
   4136     m_smoothstreaming_mode = true;
   4137     return OMX_ErrorNone;
   4138 }
   4139 
   4140 /* ======================================================================
   4141    FUNCTION
   4142    omx_vdec::Setparameter
   4143 
   4144    DESCRIPTION
   4145    OMX Set Parameter method implementation.
   4146 
   4147    PARAMETERS
   4148    <TBD>.
   4149 
   4150    RETURN VALUE
   4151    OMX Error None if successful.
   4152 
   4153    ========================================================================== */
   4154 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   4155         OMX_IN OMX_INDEXTYPE paramIndex,
   4156         OMX_IN OMX_PTR        paramData)
   4157 {
   4158     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4159     int ret=0;
   4160     struct v4l2_format fmt;
   4161 #ifdef _ANDROID_
   4162     char property_value[PROPERTY_VALUE_MAX] = {0};
   4163 #endif
   4164     if (m_state == OMX_StateInvalid) {
   4165         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   4166         return OMX_ErrorInvalidState;
   4167     }
   4168     if (paramData == NULL) {
   4169         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   4170         return OMX_ErrorBadParameter;
   4171     }
   4172     if ((m_state != OMX_StateLoaded) &&
   4173             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   4174             (m_out_bEnabled == OMX_TRUE) &&
   4175             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   4176             (m_inp_bEnabled == OMX_TRUE)) {
   4177         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   4178         return OMX_ErrorIncorrectStateOperation;
   4179     }
   4180     switch ((unsigned long)paramIndex) {
   4181         case OMX_IndexParamPortDefinition: {
   4182                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   4183                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   4184                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   4185                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   4186                                //been called.
   4187                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
   4188                                        (int)portDefn->format.video.nFrameHeight,
   4189                                        (int)portDefn->format.video.nFrameWidth);
   4190 
   4191                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4192                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
   4193                                                           portDefn->nBufferCountActual);
   4194                                    eRet = OMX_ErrorBadParameter;
   4195                                    break;
   4196                                }
   4197                                if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
   4198                                    if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
   4199                                         portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
   4200                                         DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
   4201                                                           portDefn->nBufferCountActual, portDefn->nBufferSize);
   4202                                         eRet = OMX_ErrorBadParameter;
   4203                                         break;
   4204                                    }
   4205                                     m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
   4206                                             portDefn->nBufferCountActual);
   4207                                     break;
   4208                                }
   4209 
   4210                                if (OMX_DirOutput == portDefn->eDir) {
   4211                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
   4212                                    bool port_format_changed = false;
   4213                                    m_display_id = portDefn->format.video.pNativeWindow;
   4214                                    unsigned int buffer_size;
   4215                                    /* update output port resolution with client supplied dimensions
   4216                                       in case scaling is enabled, else it follows input resolution set
   4217                                    */
   4218                                    decide_dpb_buffer_mode(is_down_scalar_enabled);
   4219                                    if (is_down_scalar_enabled) {
   4220                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
   4221                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4222                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4223                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   4224                                                portDefn->format.video.nFrameWidth != 0x0) {
   4225                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4226                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4227                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   4228                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   4229                                            if (ret) {
   4230                                                DEBUG_PRINT_ERROR("Get Resolution failed");
   4231                                                eRet = OMX_ErrorHardware;
   4232                                                break;
   4233                                            }
   4234                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
   4235                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
   4236                                                    port_format_changed = true;
   4237                                            }
   4238 
   4239                                            /* set crop info */
   4240                                            rectangle.nLeft = 0;
   4241                                            rectangle.nTop = 0;
   4242                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
   4243                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
   4244 
   4245                                            m_extradata_info.output_crop_rect.nLeft = 0;
   4246                                            m_extradata_info.output_crop_rect.nTop = 0;
   4247                                            m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth;
   4248                                            m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight;
   4249 
   4250                                            eRet = is_video_session_supported();
   4251                                            if (eRet)
   4252                                                break;
   4253                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4254                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4255                                            fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
   4256                                            fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
   4257                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   4258                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
   4259                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
   4260                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4261                                            if (ret) {
   4262                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4263                                                eRet = OMX_ErrorUnsupportedSetting;
   4264                                            } else
   4265                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   4266                                        }
   4267 
   4268                                        if (eRet) {
   4269                                            break;
   4270                                        }
   4271 
   4272                                        if (secure_mode) {
   4273                                            struct v4l2_control control;
   4274                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
   4275                                            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   4276                                                DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
   4277                                                eRet = OMX_ErrorHardware;
   4278                                            } else {
   4279                                                /* This is a workaround for a bug in fw which uses stride
   4280                                                 * and slice instead of width and height to check against
   4281                                                 * the threshold.
   4282                                                 */
   4283                                                OMX_U32 stride, slice;
   4284                                                if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   4285                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
   4286                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
   4287                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   4288                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth);
   4289                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight);
   4290                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   4291                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameWidth);
   4292                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameHeight);
   4293                                                } else {
   4294                                                    stride = portDefn->format.video.nFrameWidth;
   4295                                                    slice = portDefn->format.video.nFrameHeight;
   4296                                                }
   4297 
   4298                                                DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
   4299                                                DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
   4300 
   4301                                                if (stride * slice <= (OMX_U32)control.value) {
   4302                                                    secure_scaling_to_non_secure_opb = true;
   4303                                                    DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
   4304                                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
   4305                                                    control.value = 1;
   4306                                                    if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   4307                                                        DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
   4308                                                        eRet = OMX_ErrorUnsupportedSetting;
   4309                                                    }
   4310                                                }
   4311                                            }
   4312                                        }
   4313                                    }
   4314 
   4315                                    if (eRet) {
   4316                                        break;
   4317                                    }
   4318 
   4319                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4320                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
   4321                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4322                                        eRet = OMX_ErrorBadParameter;
   4323                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
   4324                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
   4325                                        eRet = OMX_ErrorBadParameter;
   4326                                    } else if (!port_format_changed) {
   4327 
   4328                                        // Buffer count can change only when port is unallocated
   4329                                        if (m_out_mem_ptr &&
   4330                                                 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
   4331                                                 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
   4332 
   4333                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
   4334                                            eRet = OMX_ErrorInvalidState;
   4335                                            break;
   4336                                        }
   4337 
   4338                                        // route updating of buffer requirements via c2d proxy.
   4339                                        // Based on whether c2d is enabled, requirements will be handed
   4340                                        // to the vidc driver appropriately
   4341                                        eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
   4342                                                 portDefn->nBufferCountActual);
   4343                                        if (eRet == OMX_ErrorNone) {
   4344                                            m_port_def = *portDefn;
   4345                                        } else {
   4346                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
   4347                                                    drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
   4348                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4349                                            eRet = OMX_ErrorBadParameter;
   4350                                        }
   4351                                    }
   4352                                } else if (OMX_DirInput == portDefn->eDir) {
   4353                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
   4354                                    bool port_format_changed = false;
   4355                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   4356                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   4357                                        // Frame rate only should be set if this is a "known value" or to
   4358                                        // activate ts prediction logic (arbitrary mode only) sending input
   4359                                        // timestamps with max value (LLONG_MAX).
   4360                                        m_fps_received = portDefn->format.video.xFramerate;
   4361                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
   4362                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
   4363                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   4364                                                drv_ctx.frame_rate.fps_denominator);
   4365                                        if (!drv_ctx.frame_rate.fps_numerator) {
   4366                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   4367                                            drv_ctx.frame_rate.fps_numerator = 30;
   4368                                        }
   4369                                        if (drv_ctx.frame_rate.fps_denominator)
   4370                                            drv_ctx.frame_rate.fps_numerator = (int)
   4371                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   4372                                        drv_ctx.frame_rate.fps_denominator = 1;
   4373                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   4374                                            drv_ctx.frame_rate.fps_numerator;
   4375                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
   4376                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   4377                                                (float)drv_ctx.frame_rate.fps_denominator);
   4378 
   4379                                        struct v4l2_outputparm oparm;
   4380                                        /*XXX: we're providing timing info as seconds per frame rather than frames
   4381                                         * per second.*/
   4382                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   4383                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   4384 
   4385                                        struct v4l2_streamparm sparm;
   4386                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4387                                        sparm.parm.output = oparm;
   4388                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   4389                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
   4390                                            eRet = OMX_ErrorHardware;
   4391                                            break;
   4392                                        }
   4393                                        m_perf_control.request_cores(frm_int);
   4394                                    }
   4395 
   4396                                    if (drv_ctx.video_resolution.frame_height !=
   4397                                            portDefn->format.video.nFrameHeight ||
   4398                                            drv_ctx.video_resolution.frame_width  !=
   4399                                            portDefn->format.video.nFrameWidth) {
   4400                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
   4401                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4402                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4403                                        port_format_changed = true;
   4404                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
   4405                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
   4406                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
   4407                                            if (m_smoothstreaming_mode &&
   4408                                                    ((frameWidth * frameHeight) <
   4409                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
   4410                                                frameWidth = m_smoothstreaming_width;
   4411                                                frameHeight = m_smoothstreaming_height;
   4412                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
   4413                                                        "for adaptive-playback/smooth-streaming",
   4414                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
   4415                                            }
   4416 
   4417                                            m_extradata_info.output_crop_rect.nLeft = 0;
   4418                                            m_extradata_info.output_crop_rect.nTop = 0;
   4419                                            m_extradata_info.output_crop_rect.nWidth = frameWidth;
   4420                                            m_extradata_info.output_crop_rect.nHeight = frameHeight;
   4421 
   4422                                            update_resolution(frameWidth, frameHeight,
   4423                                                    frameWidth, frameHeight);
   4424                                            eRet = is_video_session_supported();
   4425                                            if (eRet)
   4426                                                break;
   4427                                            if (is_down_scalar_enabled) {
   4428                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4429                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4430                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4431                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4432                                                fmt.fmt.pix_mp.pixelformat = output_capability;
   4433                                                DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d",
   4434                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4435                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4436                                            } else {
   4437                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4438                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4439                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4440                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4441                                                fmt.fmt.pix_mp.pixelformat = output_capability;
   4442                                                DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
   4443                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4444                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4445                                                fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4446                                                fmt.fmt.pix_mp.pixelformat = capture_capability;
   4447                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4448                                            }
   4449                                            if (ret) {
   4450                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4451                                                eRet = OMX_ErrorUnsupportedSetting;
   4452                                            } else {
   4453                                                if (!is_down_scalar_enabled)
   4454                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
   4455                                            }
   4456                                        }
   4457                                    }
   4458                                    if (m_custom_buffersize.input_buffersize
   4459                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
   4460                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
   4461                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
   4462                                        eRet = OMX_ErrorBadParameter;
   4463                                        break;
   4464                                    }
   4465                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4466                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
   4467                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4468                                        eRet = OMX_ErrorBadParameter;
   4469                                        break;
   4470                                    }
   4471                                    // Buffer count can change only when port is unallocated
   4472                                    if (m_inp_mem_ptr &&
   4473                                             (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
   4474                                             portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
   4475                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
   4476                                        eRet = OMX_ErrorInvalidState;
   4477                                        break;
   4478                                    }
   4479 
   4480                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   4481                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   4482                                        port_format_changed = true;
   4483                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   4484                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   4485                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   4486                                            (~(buffer_prop->alignment - 1));
   4487                                        eRet = set_buffer_req(buffer_prop);
   4488                                    }
   4489                                    if (false == port_format_changed) {
   4490                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
   4491                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
   4492                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4493                                        eRet = OMX_ErrorBadParameter;
   4494                                    }
   4495                                } else if (portDefn->eDir ==  OMX_DirMax) {
   4496                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   4497                                            (int)portDefn->nPortIndex);
   4498                                    eRet = OMX_ErrorBadPortIndex;
   4499                                }
   4500                            }
   4501                            break;
   4502         case OMX_IndexParamVideoPortFormat: {
   4503                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   4504                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   4505                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   4506                                 int ret=0;
   4507                                 struct v4l2_format fmt;
   4508                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
   4509                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
   4510 
   4511                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4512                                 if (1 == portFmt->nPortIndex) {
   4513                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4514                                     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   4515                                     if (ret < 0) {
   4516                                         DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   4517                                         return OMX_ErrorBadParameter;
   4518                                     }
   4519                                     enum vdec_output_fromat op_format;
   4520                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4521                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   4522                                             portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4523                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
   4524                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
   4525                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   4526                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   4527                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4528                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4529                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC;
   4530                                     } else
   4531                                         eRet = OMX_ErrorBadParameter;
   4532 
   4533                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4534                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4535                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   4536                                     } else {
   4537                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
   4538                                     }
   4539 
   4540                                     if (eRet == OMX_ErrorNone) {
   4541                                         drv_ctx.output_format = op_format;
   4542                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4543                                         if (ret) {
   4544                                             DEBUG_PRINT_ERROR("Set output format failed");
   4545                                             eRet = OMX_ErrorUnsupportedSetting;
   4546                                             /*TODO: How to handle this case */
   4547                                         } else {
   4548                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   4549                                         }
   4550                                     }
   4551                                     if (eRet == OMX_ErrorNone) {
   4552                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   4553                                             DEBUG_PRINT_ERROR("Set color format failed");
   4554                                             eRet = OMX_ErrorBadParameter;
   4555                                         }
   4556                                     }
   4557                                 }
   4558                             }
   4559                             break;
   4560 
   4561         case OMX_QcomIndexPortDefn: {
   4562                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
   4563                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   4564                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   4565                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
   4566                                     (unsigned int)portFmt->nFramePackingFormat);
   4567 
   4568                             /* Input port */
   4569                             if (portFmt->nPortIndex == 0) {
   4570                                 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
   4571                                 //   - headers are allocated and
   4572                                 //   - headers-indices are derived
   4573                                 // Avoid changing arbitrary_bytes when the port is already allocated
   4574                                 if (m_inp_mem_ptr) {
   4575                                     DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
   4576                                     return OMX_ErrorUnsupportedSetting;
   4577                                 }
   4578                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   4579                                     if (secure_mode || m_input_pass_buffer_fd) {
   4580                                         arbitrary_bytes = false;
   4581                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
   4582                                         eRet = OMX_ErrorUnsupportedSetting;
   4583                                     } else {
   4584                                         arbitrary_bytes = true;
   4585                                     }
   4586                                 } else if (portFmt->nFramePackingFormat ==
   4587                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   4588                                     arbitrary_bytes = false;
   4589 #ifdef _ANDROID_
   4590                                     property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   4591                                     if (atoi(property_value)) {
   4592                                         DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
   4593                                         arbitrary_bytes = true;
   4594                                     }
   4595 #endif
   4596                                 } else {
   4597                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
   4598                                             (unsigned int)portFmt->nFramePackingFormat);
   4599                                     eRet = OMX_ErrorUnsupportedSetting;
   4600                                 }
   4601                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4602                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
   4603                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   4604                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   4605                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   4606                                     m_out_mem_region_smi = OMX_TRUE;
   4607                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4608                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
   4609                                         m_use_output_pmem = OMX_TRUE;
   4610                                     }
   4611                                 }
   4612                             }
   4613                         }
   4614                         if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   4615                                     OMX_MAX_STRINGNAME_SIZE)) {
   4616                             arbitrary_bytes = true;
   4617                             DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264");
   4618                         }
   4619                         break;
   4620 
   4621         case OMX_QTIIndexParamVideoClientExtradata: {
   4622                                   VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
   4623                                   DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
   4624                                   QOMX_EXTRADATA_ENABLE *pParam =
   4625                                       (QOMX_EXTRADATA_ENABLE *)paramData;
   4626 
   4627                                   if (m_state != OMX_StateLoaded) {
   4628                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
   4629                                       return OMX_ErrorIncorrectStateOperation;
   4630                                   }
   4631 
   4632                                   if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   4633                                       m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
   4634                                   } else {
   4635                                       DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
   4636                                       eRet = OMX_ErrorUnsupportedIndex;
   4637                                   }
   4638                                   break;
   4639                               }
   4640         case OMX_IndexParamStandardComponentRole: {
   4641                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   4642                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   4643                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   4644                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
   4645                                           comp_role->cRole);
   4646 
   4647                                   if ((m_state == OMX_StateLoaded)&&
   4648                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
   4649                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   4650                                   } else {
   4651                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4652                                       return OMX_ErrorIncorrectStateOperation;
   4653                                   }
   4654 
   4655                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4656                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4657                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
   4658                                       } else {
   4659                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4660                                           eRet =OMX_ErrorUnsupportedSetting;
   4661                                       }
   4662                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4663                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4664                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   4665                                       } else {
   4666                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4667                                           eRet = OMX_ErrorUnsupportedSetting;
   4668                                       }
   4669                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4670                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4671                                           strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
   4672                                       } else {
   4673                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4674                                           eRet = OMX_ErrorUnsupportedSetting;
   4675                                       }
   4676                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4677                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4678                                           strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
   4679                                       } else {
   4680                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4681                                           eRet =OMX_ErrorUnsupportedSetting;
   4682                                       }
   4683                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4684                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4685                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
   4686                                       } else {
   4687                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4688                                           eRet = OMX_ErrorUnsupportedSetting;
   4689                                       }
   4690                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) ||
   4691                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
   4692                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
   4693                                         ) {
   4694                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) {
   4695                                           strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
   4696                                       } else {
   4697                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4698                                           eRet =OMX_ErrorUnsupportedSetting;
   4699                                       }
   4700                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) ||
   4701                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE))
   4702                                         ) {
   4703                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   4704                                           strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
   4705                                       } else {
   4706                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4707                                           eRet =OMX_ErrorUnsupportedSetting;
   4708                                       }
   4709                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   4710                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   4711                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4712                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
   4713                                       } else {
   4714                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4715                                           eRet = OMX_ErrorUnsupportedSetting;
   4716                                       }
   4717                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   4718                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
   4719                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4720                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
   4721                                       } else {
   4722                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4723                                           eRet = OMX_ErrorUnsupportedSetting;
   4724                                       }
   4725                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4726                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4727                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   4728                                       } else {
   4729                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4730                                           eRet = OMX_ErrorUnsupportedSetting;
   4731                                       }
   4732                                   } else {
   4733                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
   4734                                       eRet = OMX_ErrorInvalidComponentName;
   4735                                   }
   4736                                   break;
   4737                               }
   4738 
   4739         case OMX_IndexParamPriorityMgmt: {
   4740                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   4741                              if (m_state != OMX_StateLoaded) {
   4742                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4743                                  return OMX_ErrorIncorrectStateOperation;
   4744                              }
   4745                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   4746                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
   4747                                      (unsigned int)priorityMgmtype->nGroupID);
   4748 
   4749                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
   4750                                      (unsigned int)priorityMgmtype->nGroupPriority);
   4751 
   4752                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   4753                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   4754 
   4755                              break;
   4756                          }
   4757 
   4758         case OMX_IndexParamCompBufferSupplier: {
   4759                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   4760                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   4761                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
   4762                                            bufferSupplierType->eBufferSupplier);
   4763                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   4764                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   4765 
   4766                                    else
   4767 
   4768                                        eRet = OMX_ErrorBadPortIndex;
   4769 
   4770                                    break;
   4771 
   4772                                }
   4773         case OMX_IndexParamVideoAvc: {
   4774                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
   4775                                      paramIndex);
   4776                              break;
   4777                          }
   4778         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   4779                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
   4780                                      paramIndex);
   4781                              break;
   4782                         }
   4783         case OMX_IndexParamVideoH263: {
   4784                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   4785                                       paramIndex);
   4786                               break;
   4787                           }
   4788         case OMX_IndexParamVideoMpeg4: {
   4789                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   4790                                        paramIndex);
   4791                                break;
   4792                            }
   4793         case OMX_IndexParamVideoMpeg2: {
   4794                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   4795                                        paramIndex);
   4796                                break;
   4797                            }
   4798         case OMX_QTIIndexParamLowLatencyMode: {
   4799                                struct v4l2_control control;
   4800                                int rc = 0;
   4801                                QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam =
   4802                                    (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData;
   4803                                if (pParam->bLowLatencyMode) {
   4804                                    DEBUG_PRINT_HIGH("Enabling DECODE order");
   4805                                    time_stamp_dts.set_timestamp_reorder_mode(false);
   4806                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4807                                    control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4808                                    rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4809                                    if (rc) {
   4810                                        DEBUG_PRINT_ERROR("Set picture order failed");
   4811                                        eRet = OMX_ErrorUnsupportedSetting;
   4812                                    }
   4813                                }
   4814                                break;
   4815                            }
   4816         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   4817                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
   4818                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   4819                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   4820                                      struct v4l2_control control;
   4821                                      int pic_order,rc=0;
   4822                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
   4823                                              pictureOrder->eOutputPictureOrder);
   4824                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   4825                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   4826                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   4827                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4828                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   4829                                      } else
   4830                                          eRet = OMX_ErrorBadParameter;
   4831                                      if (eRet == OMX_ErrorNone) {
   4832                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4833                                          control.value = pic_order;
   4834                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4835                                          if (rc) {
   4836                                              DEBUG_PRINT_ERROR("Set picture order failed");
   4837                                              eRet = OMX_ErrorUnsupportedSetting;
   4838                                          }
   4839                                      }
   4840                                      m_decode_order_mode =
   4841                                             pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
   4842                                      break;
   4843                                  }
   4844         case OMX_QcomIndexParamConcealMBMapExtraData:
   4845                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4846                                eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   4847                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4848                                break;
   4849         case OMX_QcomIndexParamFrameInfoExtraData:
   4850                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4851                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   4852                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4853                                break;
   4854         case OMX_ExtraDataFrameDimension:
   4855                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4856                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
   4857                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4858                                break;
   4859         case OMX_QcomIndexParamInterlaceExtraData:
   4860                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4861                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   4862                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4863                                break;
   4864         case OMX_QcomIndexParamH264TimeInfo:
   4865                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4866                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   4867                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4868                                break;
   4869         case OMX_QcomIndexParamVideoFramePackingExtradata:
   4870                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4871                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
   4872                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4873                                break;
   4874         case OMX_QcomIndexParamVideoQPExtraData:
   4875                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4876                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4877                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4878                                break;
   4879         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
   4880                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4881                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
   4882                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4883                                break;
   4884         case OMX_QcomIndexEnableExtnUserData:
   4885                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4886                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
   4887                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4888                                 break;
   4889         case OMX_QTIIndexParamVQZipSEIExtraData:
   4890                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4891                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4892                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4893                                 break;
   4894         case OMX_QcomIndexParamVideoDivx: {
   4895                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   4896                           }
   4897                           break;
   4898         case OMX_QcomIndexPlatformPvt: {
   4899                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN);
   4900                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
   4901                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   4902                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4903                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   4904                                    eRet = OMX_ErrorUnsupportedSetting;
   4905                                } else {
   4906                                    m_out_pvt_entry_pmem = OMX_TRUE;
   4907                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4908                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
   4909                                        m_use_output_pmem = OMX_TRUE;
   4910                                    }
   4911                                }
   4912 
   4913                            }
   4914                            break;
   4915         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   4916                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   4917                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   4918                                        struct v4l2_control control;
   4919                                        int rc;
   4920                                        drv_ctx.idr_only_decoding = 1;
   4921                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4922                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4923                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4924                                        if (rc) {
   4925                                            DEBUG_PRINT_ERROR("Set picture order failed");
   4926                                            eRet = OMX_ErrorUnsupportedSetting;
   4927                                        } else {
   4928                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   4929                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   4930                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4931                                            if (rc) {
   4932                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
   4933                                                eRet = OMX_ErrorUnsupportedSetting;
   4934                                            }
   4935                                            /*Setting sync frame decoding on driver might change buffer
   4936                                             * requirements so update them here*/
   4937                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   4938                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
   4939                                                eRet = OMX_ErrorUnsupportedSetting;
   4940                                            }
   4941                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   4942                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
   4943                                                eRet = OMX_ErrorUnsupportedSetting;
   4944                                            }
   4945                                        }
   4946                                    }
   4947                                    break;
   4948 
   4949         case OMX_QcomIndexParamIndexExtraDataType: {
   4950                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
   4951                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   4952                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   4953                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
   4954                                             (extradataIndexType->nPortIndex == 1)) {
   4955                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
   4956                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   4957 
   4958                                     }
   4959                                 }
   4960                                 break;
   4961         case OMX_QcomIndexParamEnableSmoothStreaming: {
   4962 #ifndef SMOOTH_STREAMING_DISABLED
   4963                                       eRet = enable_smoothstreaming();
   4964 #else
   4965                                       eRet = OMX_ErrorUnsupportedSetting;
   4966 #endif
   4967                                   }
   4968                                   break;
   4969 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4970                                   /* Need to allow following two set_parameters even in Idle
   4971                                    * state. This is ANDROID architecture which is not in sync
   4972                                    * with openmax standard. */
   4973         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   4974                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
   4975                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   4976                                            if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   4977                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
   4978                                                 eRet = OMX_ErrorUnsupportedSetting;
   4979                                                 break;
   4980                                            } else if (m_out_mem_ptr) {
   4981                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
   4982                                                 eRet = OMX_ErrorInvalidState;
   4983                                                 break;
   4984                                            }
   4985                                            if (enableNativeBuffers) {
   4986                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   4987                                            }
   4988 #if !defined(FLEXYUV_SUPPORTED)
   4989                                            if (m_enable_android_native_buffers) {
   4990                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
   4991                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
   4992                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
   4993                                                    eRet = OMX_ErrorUnsupportedSetting;
   4994                                                }
   4995                                            }
   4996 #endif
   4997                                        }
   4998                                        break;
   4999         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   5000                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
   5001                                        eRet = use_android_native_buffer(hComp, paramData);
   5002                                    }
   5003                                    break;
   5004 #if ALLOCATE_OUTPUT_NATIVEHANDLE
   5005         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
   5006 
   5007                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
   5008                 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
   5009 
   5010                 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   5011                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!");
   5012                     eRet = OMX_ErrorUnsupportedSetting;
   5013                     break;
   5014                 } else if (m_inp_mem_ptr) {
   5015                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
   5016                     eRet = OMX_ErrorInvalidState;
   5017                     break;
   5018                 }
   5019 
   5020                 if (allocateNativeHandleParams != NULL) {
   5021                     allocate_native_handle = allocateNativeHandleParams->enable;
   5022                 }
   5023             }
   5024             break;
   5025 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
   5026 #endif
   5027         case OMX_QcomIndexParamEnableTimeStampReorder: {
   5028                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
   5029                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   5030                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   5031                                            if (reorder->bEnable == OMX_TRUE) {
   5032                                                frm_int =0;
   5033                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   5034                                            } else
   5035                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   5036                                        } else {
   5037                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   5038                                            if (reorder->bEnable == OMX_TRUE) {
   5039                                                eRet = OMX_ErrorUnsupportedSetting;
   5040                                            }
   5041                                        }
   5042                                    }
   5043                                    break;
   5044         case OMX_IndexParamVideoProfileLevelCurrent: {
   5045                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   5046                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   5047                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   5048                                      if (pParam) {
   5049                                          m_profile_lvl.eProfile = pParam->eProfile;
   5050                                          m_profile_lvl.eLevel = pParam->eLevel;
   5051                                      }
   5052                                      break;
   5053 
   5054                                  }
   5055         case OMX_QcomIndexParamVideoMetaBufferMode:
   5056         {
   5057             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
   5058             StoreMetaDataInBuffersParams *metabuffer =
   5059                 (StoreMetaDataInBuffersParams *)paramData;
   5060             if (!metabuffer) {
   5061                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   5062                 eRet = OMX_ErrorBadParameter;
   5063                 break;
   5064             }
   5065             if (m_disable_dynamic_buf_mode) {
   5066                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
   5067                 eRet = OMX_ErrorUnsupportedSetting;
   5068                 break;
   5069             }
   5070             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   5071 
   5072                     if (m_out_mem_ptr) {
   5073                         DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
   5074                         eRet = OMX_ErrorInvalidState;
   5075                         break;
   5076                     }
   5077                     //set property dynamic buffer mode to driver.
   5078                     struct v4l2_control control;
   5079                     struct v4l2_format fmt;
   5080                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   5081                     if (metabuffer->bStoreMetaData == true) {
   5082                         control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   5083                     } else {
   5084                         control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
   5085                     }
   5086                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   5087                     if (!rc) {
   5088                         DEBUG_PRINT_HIGH("%s buffer mode",
   5089                            (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
   5090                     } else {
   5091                         DEBUG_PRINT_ERROR("Failed to %s buffer mode",
   5092                            (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
   5093                     }
   5094                     dynamic_buf_mode = metabuffer->bStoreMetaData;
   5095                 } else {
   5096                     DEBUG_PRINT_ERROR(
   5097                        "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
   5098                        (unsigned int)metabuffer->nPortIndex);
   5099                     eRet = OMX_ErrorUnsupportedSetting;
   5100                 }
   5101                 break;
   5102         }
   5103         case OMX_QcomIndexParamVideoDownScalar:
   5104         {
   5105             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
   5106             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
   5107             struct v4l2_control control;
   5108             int rc;
   5109             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
   5110 
   5111             if (pParam && pParam->bEnable) {
   5112                 rc = enable_downscalar();
   5113                 if (rc < 0) {
   5114                     DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   5115                     return OMX_ErrorUnsupportedSetting;
   5116                 }
   5117                 m_force_down_scalar = pParam->bEnable;
   5118             } else {
   5119                 rc = disable_downscalar();
   5120                 if (rc < 0) {
   5121                     DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   5122                     return OMX_ErrorUnsupportedSetting;
   5123                 }
   5124                 m_force_down_scalar = pParam->bEnable;
   5125             }
   5126             break;
   5127         }
   5128 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   5129         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
   5130         {
   5131             VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
   5132             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
   5133             PrepareForAdaptivePlaybackParams* pParams =
   5134                     (PrepareForAdaptivePlaybackParams *) paramData;
   5135             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   5136                 if (!pParams->bEnable) {
   5137                     return OMX_ErrorNone;
   5138                 }
   5139                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
   5140                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
   5141                     DEBUG_PRINT_ERROR(
   5142                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
   5143                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
   5144                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
   5145                     eRet = OMX_ErrorBadParameter;
   5146                 } else {
   5147                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
   5148                 }
   5149             } else {
   5150                 DEBUG_PRINT_ERROR(
   5151                         "Prepare for adaptive playback supported only on output port");
   5152                 eRet = OMX_ErrorBadParameter;
   5153             }
   5154             break;
   5155         }
   5156 
   5157         case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
   5158         {
   5159             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   5160             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
   5161             m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   5162             if (m_disable_dynamic_buf_mode) {
   5163                 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
   5164             }
   5165             break;
   5166         }
   5167 #endif
   5168         case OMX_QcomIndexParamVideoCustomBufferSize:
   5169         {
   5170             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
   5171             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
   5172             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
   5173             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   5174                 struct v4l2_control control;
   5175                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
   5176                 control.value = pParam->nBufferSize;
   5177                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5178                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
   5179                     eRet = OMX_ErrorUnsupportedSetting;
   5180                 } else {
   5181                     eRet = get_buffer_req(&drv_ctx.ip_buf);
   5182                     if (eRet == OMX_ErrorNone) {
   5183                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
   5184                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
   5185                             m_custom_buffersize.input_buffersize);
   5186                     } else {
   5187                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
   5188                     }
   5189                 }
   5190             } else {
   5191                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
   5192                 eRet = OMX_ErrorBadParameter;
   5193             }
   5194             break;
   5195         }
   5196         case OMX_QTIIndexParamVQZIPSEIType:
   5197         {
   5198             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
   5199             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
   5200             OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
   5201                 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
   5202                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
   5203 
   5204             eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   5205                 ((QOMX_ENABLETYPE *)paramData)->bEnable);
   5206             if (eRet != OMX_ErrorNone) {
   5207                 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
   5208                 eRet = OMX_ErrorBadParameter;
   5209                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   5210                 break;
   5211             }
   5212             eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   5213                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   5214             if (eRet != OMX_ErrorNone) {
   5215                 DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
   5216                 eRet = OMX_ErrorBadParameter;
   5217                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   5218                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
   5219                 break;
   5220             }
   5221             eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   5222                         ((QOMX_ENABLETYPE *)paramData)->bEnable);
   5223             if (eRet != OMX_ErrorNone) {
   5224                 DEBUG_PRINT_ERROR("ERROR: Failed to set FrameInfo Extradata");
   5225                 eRet = OMX_ErrorBadParameter;
   5226                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   5227                 client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
   5228                 client_extradata = client_extradata & ~OMX_FRAMEINFO_EXTRADATA;
   5229             }
   5230             break;
   5231         }
   5232         case OMX_QTIIndexParamPassInputBufferFd:
   5233         {
   5234             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   5235             if (arbitrary_bytes) {
   5236                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
   5237                 eRet = OMX_ErrorUnsupportedSetting;
   5238                 break;
   5239             }
   5240 
   5241             m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   5242             if (m_input_pass_buffer_fd)
   5243                 DEBUG_PRINT_LOW("Enable passing input buffer FD");
   5244             break;
   5245         }
   5246         case OMX_QTIIndexParamForceCompressedForDPB:
   5247         {
   5248             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
   5249             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
   5250             OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
   5251                 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
   5252             if (m_disable_ubwc_mode) {
   5253                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
   5254                 eRet = OMX_ErrorUnsupportedSetting;
   5255                 break;
   5256             }
   5257             if (!paramData) {
   5258                DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
   5259                eRet = OMX_ErrorBadParameter;
   5260                break;
   5261             }
   5262 
   5263             m_force_compressed_for_dpb = pParam->bEnable;
   5264             break;
   5265         }
   5266         case OMX_QTIIndexParamForceUnCompressedForOPB:
   5267         {
   5268             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
   5269             OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
   5270                 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
   5271             if (!paramData) {
   5272                 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
   5273                 eRet = OMX_ErrorBadParameter;
   5274                 break;
   5275             }
   5276             m_disable_ubwc_mode = pParam->bEnable;
   5277             DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
   5278             break;
   5279         }
   5280         case OMX_QTIIndexParamDitherControl:
   5281         {
   5282             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
   5283             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamDitherControl");
   5284             QOMX_VIDEO_DITHER_CONTROL *pParam = (QOMX_VIDEO_DITHER_CONTROL *)paramData;
   5285             DEBUG_PRINT_LOW("set_parameter: Dither Config from client is: %d", pParam->eDitherType);
   5286             if (( pParam->eDitherType < QOMX_DITHER_DISABLE ) ||
   5287                 ( pParam->eDitherType > QOMX_DITHER_ALL_COLORSPACE)) {
   5288                 DEBUG_PRINT_ERROR("set_parameter: DitherType outside the range");
   5289                 eRet = OMX_ErrorBadParameter;
   5290                 break;
   5291             }
   5292             m_dither_config = is_platform_tp10capture_supported() ? (dither_type)pParam->eDitherType : DITHER_ALL_COLORSPACE;
   5293             DEBUG_PRINT_LOW("set_parameter: Final Dither Config is: %d", m_dither_config);
   5294             break;
   5295         }
   5296         default: {
   5297                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
   5298                  eRet = OMX_ErrorUnsupportedIndex;
   5299              }
   5300     }
   5301     if (eRet != OMX_ErrorNone)
   5302         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
   5303     return eRet;
   5304 }
   5305 
   5306 /* ======================================================================
   5307    FUNCTION
   5308    omx_vdec::GetConfig
   5309 
   5310    DESCRIPTION
   5311    OMX Get Config Method implementation.
   5312 
   5313    PARAMETERS
   5314    <TBD>.
   5315 
   5316    RETURN VALUE
   5317    OMX Error None if successful.
   5318 
   5319    ========================================================================== */
   5320 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   5321         OMX_IN OMX_INDEXTYPE configIndex,
   5322         OMX_INOUT OMX_PTR     configData)
   5323 {
   5324     (void) hComp;
   5325     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5326 
   5327     if (m_state == OMX_StateInvalid) {
   5328         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   5329         return OMX_ErrorInvalidState;
   5330     }
   5331 
   5332     switch ((unsigned long)configIndex) {
   5333         case OMX_QcomIndexConfigInterlaced: {
   5334                                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE);
   5335                                 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   5336                                     (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   5337                                 if (configFmt->nPortIndex == 1) {
   5338                                     if (configFmt->nIndex == 0) {
   5339                                         configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   5340                                     } else if (configFmt->nIndex == 1) {
   5341                                         configFmt->eInterlaceType =
   5342                                             OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   5343                                     } else if (configFmt->nIndex == 2) {
   5344                                         configFmt->eInterlaceType =
   5345                                             OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   5346                                     } else {
   5347                                         DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   5348                                                 " NoMore Interlaced formats");
   5349                                         eRet = OMX_ErrorNoMore;
   5350                                     }
   5351 
   5352                                 } else {
   5353                                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
   5354                                             (int)configFmt->nPortIndex);
   5355                                     eRet = OMX_ErrorBadPortIndex;
   5356                                 }
   5357                                 break;
   5358                             }
   5359         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
   5360                                      VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
   5361                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   5362                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   5363                                      decoderinstances->nNumOfInstances = 16;
   5364                                      /*TODO: How to handle this case */
   5365                                      break;
   5366                                  }
   5367         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
   5368                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   5369                                               VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   5370                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
   5371                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
   5372                                               memcpy(configFmt, &m_frame_pack_arrangement,
   5373                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   5374                                           } else {
   5375                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
   5376                                           }
   5377                                           break;
   5378                                       }
   5379         case OMX_IndexConfigCommonOutputCrop: {
   5380                                   VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
   5381                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   5382                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   5383                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
   5384                                         rectangle.nLeft, rectangle.nTop,
   5385                                         rectangle.nWidth, rectangle.nHeight);
   5386                                   break;
   5387                               }
   5388         case OMX_QcomIndexConfigPerfLevel: {
   5389                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
   5390                 struct v4l2_control control;
   5391                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   5392                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   5393 
   5394                 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5395                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   5396                     DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
   5397                     eRet = OMX_ErrorHardware;
   5398                 }
   5399 
   5400                 if (eRet == OMX_ErrorNone) {
   5401                     switch (control.value) {
   5402                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
   5403                             perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
   5404                             break;
   5405                         default:
   5406                             DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
   5407                             /* Fall through */
   5408                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
   5409                             perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
   5410                             break;
   5411                     }
   5412                 }
   5413 
   5414                 break;
   5415         }
   5416         case OMX_QcomIndexConfigH264EntropyCodingCabac: {
   5417             VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
   5418             QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
   5419             struct v4l2_control control;
   5420 
   5421             if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
   5422                 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
   5423                 eRet = OMX_ErrorNotImplemented;
   5424                 break;
   5425             }
   5426 
   5427             control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   5428             if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
   5429                 coding->bCabac = (OMX_BOOL)
   5430                     (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
   5431                 /* We can't query driver at the moment for the cabac mode, so
   5432                  * just use 0xff...f as a place holder for future improvement */
   5433                 coding->nCabacInitIdc = ~0;
   5434             } else {
   5435                 eRet = OMX_ErrorUnsupportedIndex;
   5436             }
   5437 
   5438             break;
   5439         }
   5440         case OMX_QTIIndexConfigDescribeColorAspects:
   5441         {
   5442             VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5443             DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5444 
   5445             if (params->bRequestingDataSpace) {
   5446                 DEBUG_PRINT_HIGH("Does not handle dataspace request");
   5447                 return OMX_ErrorUnsupportedSetting;
   5448             }
   5449 
   5450             print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
   5451             print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
   5452 
   5453             // For VPX, use client-color if specified.
   5454             // For the rest, try to use the stream-color if present
   5455             bool preferClientColor = (output_capability == V4L2_PIX_FMT_VP8 ||
   5456                     output_capability == V4L2_PIX_FMT_VP9);
   5457 
   5458             const ColorAspects &preferredColor = preferClientColor ?
   5459                     m_client_color_space.sAspects : m_internal_color_space.sAspects;
   5460             const ColorAspects &defaultColor = preferClientColor ?
   5461                     m_internal_color_space.sAspects : m_client_color_space.sAspects;
   5462 
   5463             params->sAspects.mPrimaries = preferredColor.mPrimaries != ColorAspects::PrimariesUnspecified ?
   5464                     preferredColor.mPrimaries : defaultColor.mPrimaries;
   5465             params->sAspects.mTransfer = preferredColor.mTransfer != ColorAspects::TransferUnspecified ?
   5466                     preferredColor.mTransfer : defaultColor.mTransfer;
   5467             params->sAspects.mMatrixCoeffs = preferredColor.mMatrixCoeffs != ColorAspects::MatrixUnspecified ?
   5468                     preferredColor.mMatrixCoeffs : defaultColor.mMatrixCoeffs;
   5469             params->sAspects.mRange = preferredColor.mRange != ColorAspects::RangeUnspecified ?
   5470                     preferredColor.mRange : defaultColor.mRange;
   5471 
   5472             print_debug_color_aspects(&(params->sAspects), "GetConfig");
   5473 
   5474             break;
   5475         }
   5476         case OMX_QTIIndexConfigDescribeHDRColorInfo:
   5477         {
   5478             VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
   5479             DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
   5480             auto_lock lock(m_hdr_info_client_lock);
   5481 
   5482             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "GetConfig Client HDR");
   5483             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "GetConfig Internal HDR");
   5484 
   5485             if (m_change_client_hdr_info) {
   5486                 DEBUG_PRINT_LOW("Updating Client's HDR Info with internal");
   5487                 memcpy(&m_client_hdr_info.sInfo,
   5488                        &m_internal_hdr_info.sInfo, sizeof(HDRStaticInfo));
   5489                 m_change_client_hdr_info = false;
   5490             }
   5491 
   5492             memcpy(&(params->sInfo), &(m_client_hdr_info.sInfo), sizeof(HDRStaticInfo));
   5493 
   5494             break;
   5495         }
   5496         case OMX_IndexConfigAndroidVendorExtension:
   5497         {
   5498             VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
   5499 
   5500             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
   5501                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
   5502             VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
   5503             return get_vendor_extension_config(ext);
   5504         }
   5505         default:
   5506         {
   5507             DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
   5508             eRet = OMX_ErrorBadParameter;
   5509         }
   5510 
   5511     }
   5512 
   5513     return eRet;
   5514 }
   5515 
   5516 /* ======================================================================
   5517    FUNCTION
   5518    omx_vdec::SetConfig
   5519 
   5520    DESCRIPTION
   5521    OMX Set Config method implementation
   5522 
   5523    PARAMETERS
   5524    <TBD>.
   5525 
   5526    RETURN VALUE
   5527    OMX Error None if successful.
   5528    ========================================================================== */
   5529 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   5530         OMX_IN OMX_INDEXTYPE configIndex,
   5531         OMX_IN OMX_PTR        configData)
   5532 {
   5533     (void) hComp;
   5534     if (m_state == OMX_StateInvalid) {
   5535         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   5536         return OMX_ErrorInvalidState;
   5537     }
   5538 
   5539     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5540     OMX_VIDEO_CONFIG_NALSIZE *pNal;
   5541 
   5542     DEBUG_PRINT_LOW("Set Config Called");
   5543 
   5544     if (configIndex == OMX_IndexConfigVideoNalSize) {
   5545         struct v4l2_control temp;
   5546         temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
   5547 
   5548         VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE);
   5549         pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   5550         switch (pNal->nNaluBytes) {
   5551             case 0:
   5552                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
   5553                 break;
   5554             case 2:
   5555                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
   5556                 break;
   5557             case 4:
   5558                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
   5559                 break;
   5560             default:
   5561                 return OMX_ErrorUnsupportedSetting;
   5562         }
   5563 
   5564         if (!arbitrary_bytes) {
   5565             /* In arbitrary bytes mode, the assembler strips out nal size and replaces
   5566              * with start code, so only need to notify driver in frame by frame mode */
   5567             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
   5568                 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
   5569                 return OMX_ErrorHardware;
   5570             }
   5571         }
   5572 
   5573         nal_length = pNal->nNaluBytes;
   5574         m_frame_parser.init_nal_length(nal_length);
   5575 
   5576         DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
   5577         return ret;
   5578     } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
   5579         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   5580         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
   5581 
   5582         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   5583             if (config->bEnabled) {
   5584                 if ((config->nFps >> 16) > 0 &&
   5585                         (config->nFps >> 16) <= MAX_SUPPORTED_FPS) {
   5586                     m_fps_received = config->nFps;
   5587                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
   5588                             (unsigned int)config->nFps >> 16);
   5589                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   5590                             drv_ctx.frame_rate.fps_denominator);
   5591 
   5592                     if (!drv_ctx.frame_rate.fps_numerator) {
   5593                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   5594                         drv_ctx.frame_rate.fps_numerator = 30;
   5595                     }
   5596 
   5597                     if (drv_ctx.frame_rate.fps_denominator) {
   5598                         drv_ctx.frame_rate.fps_numerator = (int)
   5599                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   5600                     }
   5601 
   5602                     drv_ctx.frame_rate.fps_denominator = 1;
   5603                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   5604                         drv_ctx.frame_rate.fps_numerator;
   5605 
   5606                     struct v4l2_outputparm oparm;
   5607                     /*XXX: we're providing timing info as seconds per frame rather than frames
   5608                      * per second.*/
   5609                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   5610                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   5611 
   5612                     struct v4l2_streamparm sparm;
   5613                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5614                     sparm.parm.output = oparm;
   5615                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   5616                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   5617                                 performance might be affected");
   5618                         ret = OMX_ErrorHardware;
   5619                     }
   5620                     client_set_fps = true;
   5621                 } else {
   5622                     DEBUG_PRINT_ERROR("Frame rate not supported.");
   5623                     ret = OMX_ErrorUnsupportedSetting;
   5624                 }
   5625             } else {
   5626                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   5627                 client_set_fps = false;
   5628             }
   5629         } else {
   5630             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   5631                     (int)config->nPortIndex);
   5632             ret = OMX_ErrorBadPortIndex;
   5633         }
   5634 
   5635         return ret;
   5636     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
   5637         OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   5638             (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   5639         struct v4l2_control control;
   5640 
   5641         DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
   5642         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5643 
   5644         switch (perf->ePerfLevel) {
   5645             case OMX_QCOM_PerfLevelNominal:
   5646                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   5647                 m_need_turbo &= ~TURBO_MODE_CLIENT_REQUESTED;
   5648                 break;
   5649             case OMX_QCOM_PerfLevelTurbo:
   5650                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   5651                 m_need_turbo |= TURBO_MODE_CLIENT_REQUESTED;
   5652                 break;
   5653             default:
   5654                 ret = OMX_ErrorUnsupportedSetting;
   5655                 break;
   5656         }
   5657 
   5658         if (ret == OMX_ErrorNone) {
   5659             ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5660                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5661         }
   5662 
   5663         return ret;
   5664     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
   5665         OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
   5666             (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
   5667         struct v4l2_control control;
   5668         DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
   5669         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
   5670 
   5671         switch (config->eDecodeType) {
   5672             case OMX_QCOM_PictypeDecode_I:
   5673                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON;
   5674                 break;
   5675             case OMX_QCOM_PictypeDecode_IPB:
   5676             default:
   5677                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF;
   5678                 break;
   5679         }
   5680 
   5681         ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5682                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5683         if (ret)
   5684             DEBUG_PRINT_ERROR("Failed to set picture type decode");
   5685 
   5686         return ret;
   5687     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
   5688         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
   5689         DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
   5690 
   5691         struct v4l2_control control;
   5692 
   5693         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   5694         if (priority->nU32 == 0)
   5695             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
   5696         else
   5697             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   5698 
   5699         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5700             DEBUG_PRINT_ERROR("Failed to set Priority");
   5701             ret = OMX_ErrorUnsupportedSetting;
   5702         }
   5703         return ret;
   5704     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
   5705         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
   5706         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
   5707 
   5708         struct v4l2_control control;
   5709 
   5710         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
   5711         control.value = rate->nU32;
   5712 
   5713         operating_frame_rate = rate->nU32 >> 16;
   5714 
   5715         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5716             ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
   5717                     OMX_ErrorUnsupportedSetting;
   5718             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
   5719                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
   5720         }
   5721         return ret;
   5722 
   5723     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
   5724         VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5725         DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5726         if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
   5727             enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true);
   5728         }
   5729 
   5730         print_debug_color_aspects(&(params->sAspects), "Set Config");
   5731         memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
   5732         return ret;
   5733     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeHDRColorInfo) {
   5734         VALIDATE_OMX_PARAM_DATA(configData, DescribeHDRStaticInfoParams);
   5735         DescribeHDRStaticInfoParams *params = (DescribeHDRStaticInfoParams *)configData;
   5736         if (!DEFAULT_EXTRADATA & OMX_HDR_COLOR_INFO_EXTRADATA) {
   5737             ret = enable_extradata(OMX_HDR_COLOR_INFO_EXTRADATA, true, true);
   5738             if (ret != OMX_ErrorNone) {
   5739                 DEBUG_PRINT_ERROR("Failed to enable OMX_HDR_COLOR_INFO_EXTRADATA");
   5740                 return ret;
   5741             }
   5742         }
   5743 
   5744         print_debug_hdr_color_info(&(params->sInfo), "Set Config HDR");
   5745         memcpy(&m_client_hdr_info, params, sizeof(DescribeHDRStaticInfoParams));
   5746         return ret;
   5747 
   5748     } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
   5749         VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
   5750 
   5751         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
   5752                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
   5753         VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
   5754 
   5755         return set_vendor_extension_config(ext);
   5756     }
   5757 
   5758     return OMX_ErrorNotImplemented;
   5759 }
   5760 
   5761 #define extn_equals(param, extn) (!strcmp(param, extn))
   5762 
   5763 /* ======================================================================
   5764    FUNCTION
   5765    omx_vdec::GetExtensionIndex
   5766 
   5767    DESCRIPTION
   5768    OMX GetExtensionIndex method implementaion.  <TBD>
   5769 
   5770    PARAMETERS
   5771    <TBD>.
   5772 
   5773    RETURN VALUE
   5774    OMX Error None if everything successful.
   5775 
   5776    ========================================================================== */
   5777 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   5778         OMX_IN OMX_STRING      paramName,
   5779         OMX_OUT OMX_INDEXTYPE* indexType)
   5780 {
   5781     (void) hComp;
   5782     if (m_state == OMX_StateInvalid) {
   5783         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
   5784         return OMX_ErrorInvalidState;
   5785     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
   5786         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
   5787     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
   5788         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
   5789     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
   5790         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
   5791     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
   5792         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
   5793     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
   5794         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
   5795     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
   5796         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
   5797     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
   5798         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
   5799     }
   5800 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   5801     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
   5802         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   5803     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
   5804         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   5805     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
   5806         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   5807     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
   5808         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   5809     }
   5810 #if ALLOCATE_OUTPUT_NATIVEHANDLE
   5811     else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
   5812         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
   5813     }
   5814 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
   5815 #endif
   5816     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   5817         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   5818     }
   5819 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   5820     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
   5821         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
   5822     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
   5823         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
   5824     }
   5825 #endif
   5826 #ifdef FLEXYUV_SUPPORTED
   5827     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
   5828         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
   5829     }
   5830 #endif
   5831     else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
   5832         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
   5833     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
   5834         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
   5835     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
   5836         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
   5837     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.LowLatency")) {
   5838         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamLowLatencyMode;
   5839     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_CLIENT_EXTRADATA)) {
   5840         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoClientExtradata;
   5841     } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
   5842         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
   5843     } else if (extn_equals(paramName, "OMX.google.android.index.describeHDRStaticInfo")) {
   5844         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeHDRColorInfo;
   5845     } else {
   5846         DEBUG_PRINT_HIGH("Extension: %s not implemented", paramName);
   5847         return OMX_ErrorNotImplemented;
   5848     }
   5849     return OMX_ErrorNone;
   5850 }
   5851 
   5852 /* ======================================================================
   5853    FUNCTION
   5854    omx_vdec::GetState
   5855 
   5856    DESCRIPTION
   5857    Returns the state information back to the caller.<TBD>
   5858 
   5859    PARAMETERS
   5860    <TBD>.
   5861 
   5862    RETURN VALUE
   5863    Error None if everything is successful.
   5864    ========================================================================== */
   5865 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   5866         OMX_OUT OMX_STATETYPE* state)
   5867 {
   5868     (void) hComp;
   5869     *state = m_state;
   5870     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   5871     return OMX_ErrorNone;
   5872 }
   5873 
   5874 /* ======================================================================
   5875    FUNCTION
   5876    omx_vdec::ComponentTunnelRequest
   5877 
   5878    DESCRIPTION
   5879    OMX Component Tunnel Request method implementation. <TBD>
   5880 
   5881    PARAMETERS
   5882    None.
   5883 
   5884    RETURN VALUE
   5885    OMX Error None if everything successful.
   5886 
   5887    ========================================================================== */
   5888 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   5889         OMX_IN OMX_U32                        port,
   5890         OMX_IN OMX_HANDLETYPE        peerComponent,
   5891         OMX_IN OMX_U32                    peerPort,
   5892         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   5893 {
   5894     (void) hComp;
   5895     (void) port;
   5896     (void) peerComponent;
   5897     (void) peerPort;
   5898     (void) tunnelSetup;
   5899     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
   5900     return OMX_ErrorNotImplemented;
   5901 }
   5902 
   5903 /* ======================================================================
   5904    FUNCTION
   5905    omx_vdec::UseOutputBuffer
   5906 
   5907    DESCRIPTION
   5908    Helper function for Use buffer in the input pin
   5909 
   5910    PARAMETERS
   5911    None.
   5912 
   5913    RETURN VALUE
   5914    true/false
   5915 
   5916    ========================================================================== */
   5917 OMX_ERRORTYPE omx_vdec::allocate_extradata()
   5918 {
   5919 #ifdef USE_ION
   5920     if (drv_ctx.extradata_info.buffer_size) {
   5921         if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
   5922             munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5923             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5924             free_ion_memory(&drv_ctx.extradata_info.ion);
   5925         }
   5926         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
   5927         drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
   5928                 drv_ctx.extradata_info.size, 4096,
   5929                 &drv_ctx.extradata_info.ion.ion_alloc_data,
   5930                 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
   5931         if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
   5932             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
   5933             return OMX_ErrorInsufficientResources;
   5934         }
   5935         drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
   5936                 drv_ctx.extradata_info.size,
   5937                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5938                 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
   5939         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
   5940             DEBUG_PRINT_ERROR("Failed to map extradata memory");
   5941             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5942             free_ion_memory(&drv_ctx.extradata_info.ion);
   5943             return OMX_ErrorInsufficientResources;
   5944         }
   5945     }
   5946 #endif
   5947     if (!m_other_extradata) {
   5948         m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
   5949         if (!m_other_extradata) {
   5950             DEBUG_PRINT_ERROR("Failed to alloc memory\n");
   5951             return OMX_ErrorInsufficientResources;
   5952         }
   5953     }
   5954     return OMX_ErrorNone;
   5955 }
   5956 
   5957 void omx_vdec::free_extradata()
   5958 {
   5959 #ifdef USE_ION
   5960     if (drv_ctx.extradata_info.uaddr) {
   5961         munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5962         close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5963         free_ion_memory(&drv_ctx.extradata_info.ion);
   5964     }
   5965 #endif
   5966     if (m_other_extradata) {
   5967         free(m_other_extradata);
   5968         m_other_extradata = NULL;
   5969     }
   5970 }
   5971 
   5972 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
   5973         OMX_IN OMX_HANDLETYPE            hComp,
   5974         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5975         OMX_IN OMX_U32                   port,
   5976         OMX_IN OMX_PTR                   appData,
   5977         OMX_IN OMX_U32                   bytes,
   5978         OMX_IN OMX_U8*                   buffer)
   5979 {
   5980     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5981     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   5982     unsigned                         i= 0; // Temporary counter
   5983     struct vdec_setbuffer_cmd setbuffers;
   5984     OMX_PTR privateAppData = NULL;
   5985     private_handle_t *handle = NULL;
   5986     OMX_U8 *buff = buffer;
   5987     struct v4l2_buffer buf;
   5988     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5989     int extra_idx = 0;
   5990     (void) hComp;
   5991     (void) port;
   5992 
   5993     if (!m_out_mem_ptr) {
   5994         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
   5995         eRet = allocate_output_headers();
   5996         if (eRet == OMX_ErrorNone)
   5997             eRet = allocate_extradata();
   5998     }
   5999 
   6000     if (eRet == OMX_ErrorNone) {
   6001         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   6002             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   6003                 break;
   6004             }
   6005         }
   6006     }
   6007 
   6008     if (i >= drv_ctx.op_buf.actualcount) {
   6009         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
   6010         eRet = OMX_ErrorInsufficientResources;
   6011     }
   6012 
   6013     if (eRet != OMX_ErrorNone)
   6014        return eRet;
   6015 
   6016     if (dynamic_buf_mode) {
   6017         *bufferHdr = (m_out_mem_ptr + i );
   6018         (*bufferHdr)->pBuffer = NULL;
   6019         if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
   6020             enum v4l2_buf_type buf_type;
   6021             int rr = 0;
   6022             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6023             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
   6024                 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
   6025                 return OMX_ErrorInsufficientResources;
   6026             } else {
   6027                 streaming[CAPTURE_PORT] = true;
   6028                 DEBUG_PRINT_LOW("STREAMON Successful");
   6029             }
   6030 
   6031             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   6032             request_perf_level(VIDC_TURBO);
   6033         }
   6034         BITMASK_SET(&m_out_bm_count,i);
   6035         (*bufferHdr)->pAppPrivate = appData;
   6036         (*bufferHdr)->pBuffer = buffer;
   6037         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   6038         return eRet;
   6039     }
   6040 
   6041     if (eRet == OMX_ErrorNone) {
   6042 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   6043         if (m_enable_android_native_buffers) {
   6044             if (m_use_android_native_buffers) {
   6045                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   6046                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   6047                 handle = (private_handle_t *)nBuf->handle;
   6048                 privateAppData = params->pAppPrivate;
   6049             } else {
   6050                 handle = (private_handle_t *)buff;
   6051                 privateAppData = appData;
   6052             }
   6053             if (!handle) {
   6054                 DEBUG_PRINT_ERROR("handle is invalid");
   6055                 return OMX_ErrorBadParameter;
   6056             }
   6057 
   6058             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   6059                 if (secure_mode && secure_scaling_to_non_secure_opb) {
   6060                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
   6061                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   6062                 } else {
   6063                     DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   6064                             " expected %u, got %u",
   6065                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   6066                     return OMX_ErrorBadParameter;
   6067                 }
   6068             }
   6069 
   6070             drv_ctx.op_buf.buffer_size = handle->size;
   6071 
   6072             if (!m_use_android_native_buffers) {
   6073                 if (!secure_mode) {
   6074                     buff =  (OMX_U8*)mmap(0, handle->size,
   6075                             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   6076                     if (buff == MAP_FAILED) {
   6077                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   6078                         return OMX_ErrorInsufficientResources;
   6079                     }
   6080                 }
   6081             }
   6082 #if defined(_ANDROID_ICS_)
   6083             native_buffer[i].nativehandle = handle;
   6084             native_buffer[i].privatehandle = handle;
   6085 #endif
   6086             if (!handle) {
   6087                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   6088                 return OMX_ErrorBadParameter;
   6089             }
   6090             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   6091             drv_ctx.ptr_outputbuffer[i].offset = 0;
   6092             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   6093             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   6094             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   6095         } else
   6096 #endif
   6097 
   6098             if (!ouput_egl_buffers && !m_use_output_pmem) {
   6099 #ifdef USE_ION
   6100                 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   6101                         drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   6102                         &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   6103                         &drv_ctx.op_buf_ion_info[i].fd_ion_data,
   6104                         secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
   6105                 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   6106                     DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   6107                     return OMX_ErrorInsufficientResources;
   6108                 }
   6109                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   6110                                       drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   6111 #else
   6112                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   6113                                       open (MEM_DEVICE,O_RDWR);
   6114 
   6115                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   6116                     DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   6117                     return OMX_ErrorInsufficientResources;
   6118                 }
   6119 
   6120                 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
   6121                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
   6122                     drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   6123                                           open (MEM_DEVICE,O_RDWR);
   6124                     if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   6125                         DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   6126                         return OMX_ErrorInsufficientResources;
   6127                     }
   6128                 }
   6129 
   6130                 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   6131                             drv_ctx.op_buf.buffer_size,
   6132                             drv_ctx.op_buf.alignment)) {
   6133                     DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6134                     close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   6135                     return OMX_ErrorInsufficientResources;
   6136                 }
   6137 #endif
   6138                 if (!secure_mode) {
   6139                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
   6140                         (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   6141                                 PROT_READ|PROT_WRITE, MAP_SHARED,
   6142                                 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   6143                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   6144                         close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   6145 #ifdef USE_ION
   6146                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   6147 #endif
   6148                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
   6149                         return OMX_ErrorInsufficientResources;
   6150                     }
   6151                 }
   6152                 drv_ctx.ptr_outputbuffer[i].offset = 0;
   6153                 privateAppData = appData;
   6154             } else {
   6155 
   6156                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   6157                 if (!appData || !bytes ) {
   6158                     if (!secure_mode && !buffer) {
   6159                         DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
   6160                         return OMX_ErrorBadParameter;
   6161                     }
   6162                 }
   6163 
   6164                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   6165                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   6166                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   6167                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
   6168                         !pmem_list->nEntries ||
   6169                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   6170                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
   6171                     return OMX_ErrorBadParameter;
   6172                 }
   6173                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   6174                     pmem_list->entryList->entry;
   6175                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   6176                         pmem_info->pmem_fd);
   6177                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   6178                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   6179                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   6180                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
   6181                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   6182                 privateAppData = appData;
   6183             }
   6184         m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   6185         m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   6186         m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   6187         m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   6188         m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   6189 
   6190         *bufferHdr = (m_out_mem_ptr + i );
   6191         if (secure_mode)
   6192             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   6193         //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   6194         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   6195                 sizeof (vdec_bufferpayload));
   6196 
   6197         DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   6198                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   6199                 drv_ctx.ptr_outputbuffer[i].pmem_fd );
   6200 
   6201         buf.index = i;
   6202         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6203         buf.memory = V4L2_MEMORY_USERPTR;
   6204         plane[0].length = drv_ctx.op_buf.buffer_size;
   6205         plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   6206             (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   6207         plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   6208         plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   6209         plane[0].data_offset = 0;
   6210         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   6211         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   6212             plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   6213             plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   6214 #ifdef USE_ION
   6215             plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   6216 #endif
   6217             plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   6218             plane[extra_idx].data_offset = 0;
   6219         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   6220             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   6221             return OMX_ErrorBadParameter;
   6222         }
   6223         buf.m.planes = plane;
   6224         buf.length = drv_ctx.num_planes;
   6225 
   6226         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
   6227             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   6228             /*TODO: How to handle this case */
   6229             return OMX_ErrorInsufficientResources;
   6230         }
   6231 
   6232         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   6233             enum v4l2_buf_type buf_type;
   6234             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6235             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   6236                 return OMX_ErrorInsufficientResources;
   6237             } else {
   6238                 streaming[CAPTURE_PORT] = true;
   6239                 DEBUG_PRINT_LOW("STREAMON Successful");
   6240             }
   6241 
   6242             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   6243             request_perf_level(VIDC_TURBO);
   6244         }
   6245 
   6246         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   6247         if (m_enable_android_native_buffers) {
   6248             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   6249             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   6250         } else {
   6251             (*bufferHdr)->pBuffer = buff;
   6252         }
   6253         (*bufferHdr)->pAppPrivate = privateAppData;
   6254         BITMASK_SET(&m_out_bm_count,i);
   6255     }
   6256     return eRet;
   6257 }
   6258 
   6259 OMX_ERRORTYPE omx_vdec::allocate_client_output_extradata_headers() {
   6260     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6261     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   6262     int i = 0;
   6263 
   6264     if (!m_client_output_extradata_mem_ptr) {
   6265         int nBufferCount       = 0;
   6266 
   6267         nBufferCount = m_client_out_extradata_info.getBufferCount();
   6268         DEBUG_PRINT_HIGH("allocate_client_output_extradata_headers buffer_count - %d", nBufferCount);
   6269 
   6270         m_client_output_extradata_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufferCount, sizeof(OMX_BUFFERHEADERTYPE));
   6271 
   6272         if (m_client_output_extradata_mem_ptr) {
   6273             bufHdr          =  m_client_output_extradata_mem_ptr;
   6274             for (i=0; i < nBufferCount; i++) {
   6275                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   6276                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   6277                 // Set the values when we determine the right HxW param
   6278                 bufHdr->nAllocLen          = 0;
   6279                 bufHdr->nFilledLen         = 0;
   6280                 bufHdr->pAppPrivate        = NULL;
   6281                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_EXTRADATA_INDEX;
   6282                 bufHdr->pBuffer            = NULL;
   6283                 bufHdr->pOutputPortPrivate = NULL;
   6284                 bufHdr++;
   6285             }
   6286         } else {
   6287              DEBUG_PRINT_ERROR("Extradata header buf mem alloc failed[0x%p]",\
   6288                     m_client_output_extradata_mem_ptr);
   6289               eRet =  OMX_ErrorInsufficientResources;
   6290         }
   6291     }
   6292     return eRet;
   6293 }
   6294 OMX_ERRORTYPE  omx_vdec::use_client_output_extradata_buffer(
   6295         OMX_IN OMX_HANDLETYPE            hComp,
   6296         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6297         OMX_IN OMX_U32                   port,
   6298         OMX_IN OMX_PTR                   appData,
   6299         OMX_IN OMX_U32                   bytes,
   6300         OMX_IN OMX_U8*                   buffer)
   6301 {
   6302     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6303     unsigned i = 0; // Temporary counter
   6304     unsigned buffer_count = m_client_out_extradata_info.getBufferCount();;
   6305     OMX_U32 buffer_size = m_client_out_extradata_info.getSize();
   6306     (void) hComp;
   6307 
   6308     if (port != OMX_CORE_OUTPUT_EXTRADATA_INDEX ||
   6309             !client_extradata || bytes != buffer_size|| bufferHdr == NULL) {
   6310         DEBUG_PRINT_ERROR("Bad Parameters PortIndex is - %d expected is- %d,"
   6311             "client_extradata - %d, bytes = %d expected is %d bufferHdr - %p", port,
   6312             OMX_CORE_OUTPUT_EXTRADATA_INDEX, client_extradata, bytes, buffer_size, bufferHdr);
   6313         eRet = OMX_ErrorBadParameter;
   6314         return eRet;
   6315     }
   6316 
   6317     if (!m_client_output_extradata_mem_ptr) {
   6318         eRet = allocate_client_output_extradata_headers();
   6319     }
   6320 
   6321     if (eRet == OMX_ErrorNone) {
   6322         for (i = 0; i < buffer_count; i++) {
   6323             if (BITMASK_ABSENT(&m_out_extradata_bm_count,i)) {
   6324                 break;
   6325             }
   6326         }
   6327     }
   6328 
   6329     if (i >= buffer_count) {
   6330         DEBUG_PRINT_ERROR("Already using %d Extradata o/p buffers", buffer_count);
   6331         eRet = OMX_ErrorInsufficientResources;
   6332     }
   6333 
   6334     if (eRet == OMX_ErrorNone) {
   6335         BITMASK_SET(&m_out_extradata_bm_count,i);
   6336         *bufferHdr = (m_client_output_extradata_mem_ptr + i );
   6337         (*bufferHdr)->pAppPrivate = appData;
   6338         (*bufferHdr)->pBuffer = buffer;
   6339         (*bufferHdr)->nAllocLen = bytes;
   6340     }
   6341 
   6342     return eRet;
   6343 }
   6344 /* ======================================================================
   6345    FUNCTION
   6346    omx_vdec::use_input_heap_buffers
   6347 
   6348    DESCRIPTION
   6349    OMX Use Buffer Heap allocation method implementation.
   6350 
   6351    PARAMETERS
   6352    <TBD>.
   6353 
   6354    RETURN VALUE
   6355    OMX Error None , if everything successful.
   6356 
   6357    ========================================================================== */
   6358 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
   6359         OMX_IN OMX_HANDLETYPE            hComp,
   6360         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6361         OMX_IN OMX_U32                   port,
   6362         OMX_IN OMX_PTR                   appData,
   6363         OMX_IN OMX_U32                   bytes,
   6364         OMX_IN OMX_U8*                   buffer)
   6365 {
   6366     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
   6367     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6368 
   6369     if (secure_mode) {
   6370         DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
   6371         return OMX_ErrorUndefined;
   6372     }
   6373 
   6374     if (!m_inp_heap_ptr)
   6375         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   6376             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   6377                     drv_ctx.ip_buf.actualcount);
   6378     if (!m_phdr_pmem_ptr)
   6379         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   6380             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   6381                     drv_ctx.ip_buf.actualcount);
   6382     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
   6383         DEBUG_PRINT_ERROR("Insufficent memory");
   6384         eRet = OMX_ErrorInsufficientResources;
   6385     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
   6386         input_use_buffer = true;
   6387         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   6388         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   6389         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   6390         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   6391         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   6392         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   6393         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   6394         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   6395         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   6396         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
   6397                     (unsigned)NULL, (unsigned)NULL)) {
   6398             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   6399             return OMX_ErrorInsufficientResources;
   6400         }
   6401         m_in_alloc_cnt++;
   6402     } else {
   6403         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
   6404         eRet = OMX_ErrorInsufficientResources;
   6405     }
   6406     return eRet;
   6407 }
   6408 
   6409 /* ======================================================================
   6410    FUNCTION
   6411    omx_vdec::UseBuffer
   6412 
   6413    DESCRIPTION
   6414    OMX Use Buffer method implementation.
   6415 
   6416    PARAMETERS
   6417    <TBD>.
   6418 
   6419    RETURN VALUE
   6420    OMX Error None , if everything successful.
   6421 
   6422    ========================================================================== */
   6423 OMX_ERRORTYPE  omx_vdec::use_buffer(
   6424         OMX_IN OMX_HANDLETYPE            hComp,
   6425         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6426         OMX_IN OMX_U32                   port,
   6427         OMX_IN OMX_PTR                   appData,
   6428         OMX_IN OMX_U32                   bytes,
   6429         OMX_IN OMX_U8*                   buffer)
   6430 {
   6431     OMX_ERRORTYPE error = OMX_ErrorNone;
   6432     struct vdec_setbuffer_cmd setbuffers;
   6433 
   6434     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
   6435             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
   6436             return OMX_ErrorBadParameter;
   6437     }
   6438     if (m_state == OMX_StateInvalid) {
   6439         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
   6440         return OMX_ErrorInvalidState;
   6441     }
   6442     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6443         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
   6444         // ensure that use-buffer was called for previous allocation.
   6445         // Mix-and-match of useBuffer and allocateBuffer is not allowed
   6446         if (m_inp_mem_ptr && !input_use_buffer) {
   6447             DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
   6448             return OMX_ErrorUndefined;
   6449         }
   6450         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   6451     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6452         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
   6453     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   6454         error = use_client_output_extradata_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
   6455     } else {
   6456         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   6457         error = OMX_ErrorBadPortIndex;
   6458     }
   6459     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
   6460     if (error == OMX_ErrorNone) {
   6461         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   6462             // Send the callback now
   6463             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   6464             post_event(OMX_CommandStateSet,OMX_StateIdle,
   6465                     OMX_COMPONENT_GENERATE_EVENT);
   6466         }
   6467         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   6468                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   6469             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   6470             post_event(OMX_CommandPortEnable,
   6471                     OMX_CORE_INPUT_PORT_INDEX,
   6472                     OMX_COMPONENT_GENERATE_EVENT);
   6473         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   6474                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   6475             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   6476             post_event(OMX_CommandPortEnable,
   6477                     OMX_CORE_OUTPUT_PORT_INDEX,
   6478                     OMX_COMPONENT_GENERATE_EVENT);
   6479         }
   6480     }
   6481     return error;
   6482 }
   6483 
   6484 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
   6485         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
   6486 {
   6487     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
   6488         if (m_inp_heap_ptr[bufferindex].pBuffer)
   6489             free(m_inp_heap_ptr[bufferindex].pBuffer);
   6490         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
   6491     }
   6492     if (pmem_bufferHdr)
   6493         free_input_buffer(pmem_bufferHdr);
   6494     return OMX_ErrorNone;
   6495 }
   6496 
   6497 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   6498 {
   6499     unsigned int index = 0;
   6500     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   6501         return OMX_ErrorBadParameter;
   6502     }
   6503 
   6504     index = bufferHdr - m_inp_mem_ptr;
   6505     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   6506 
   6507     auto_lock l(buf_lock);
   6508     bufferHdr->pInputPortPrivate = NULL;
   6509 
   6510     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   6511         DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   6512         if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
   6513             struct vdec_setbuffer_cmd setbuffers;
   6514             setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   6515             memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   6516                     sizeof (vdec_bufferpayload));
   6517             if (!secure_mode) {
   6518                 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
   6519                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
   6520                 DEBUG_PRINT_LOW("unmap the input buffer size=%u  address = %p",
   6521                         (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size,
   6522                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
   6523                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   6524                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
   6525             }
   6526 
   6527             if (allocate_native_handle){
   6528                 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
   6529                 native_handle_close(nh);
   6530                 native_handle_delete(nh);
   6531             } else {
   6532                 // Close fd for non-secure and secure non-native-handle case
   6533                 close(drv_ctx.ptr_inputbuffer[index].pmem_fd);
   6534             }
   6535             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   6536 
   6537             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
   6538                 free(m_desc_buffer_ptr[index].buf_addr);
   6539                 m_desc_buffer_ptr[index].buf_addr = NULL;
   6540                 m_desc_buffer_ptr[index].desc_data_size = 0;
   6541             }
   6542 #ifdef USE_ION
   6543             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   6544 #endif
   6545             m_in_alloc_cnt--;
   6546         }
   6547     }
   6548 
   6549     return OMX_ErrorNone;
   6550 }
   6551 
   6552 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   6553 {
   6554     unsigned int index = 0;
   6555 
   6556     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   6557         return OMX_ErrorBadParameter;
   6558     }
   6559 
   6560     index = bufferHdr - m_out_mem_ptr;
   6561     DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
   6562 
   6563     if (index < drv_ctx.op_buf.actualcount
   6564             && drv_ctx.ptr_outputbuffer) {
   6565         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
   6566                 drv_ctx.ptr_outputbuffer[index].bufferaddr);
   6567 
   6568         struct vdec_setbuffer_cmd setbuffers;
   6569         setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   6570         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   6571                 sizeof (vdec_bufferpayload));
   6572 
   6573         if (!dynamic_buf_mode) {
   6574             if (streaming[CAPTURE_PORT] &&
   6575                 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
   6576                 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   6577                     DEBUG_PRINT_ERROR("STREAMOFF Failed");
   6578                 } else {
   6579                     DEBUG_PRINT_LOW("STREAMOFF Successful");
   6580                 }
   6581             }
   6582 #ifdef _ANDROID_
   6583             if (m_enable_android_native_buffers) {
   6584                 if (!secure_mode) {
   6585                     if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   6586                         munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   6587                                 drv_ctx.ptr_outputbuffer[index].mmaped_size);
   6588                     }
   6589                 }
   6590                 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   6591             } else {
   6592 #endif
   6593                 if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0
   6594                     && !ouput_egl_buffers && !m_use_output_pmem) {
   6595                     if (drv_ctx.op_buf_map_info[index].free_buffer) {
   6596                         if (!secure_mode) {
   6597                             DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
   6598                                     drv_ctx.ptr_outputbuffer[0].pmem_fd);
   6599                             DEBUG_PRINT_LOW("unmap the ouput buffer size=%u  address = %p",
   6600                                     (unsigned int)drv_ctx.op_buf_map_info[index].map_size,
   6601                                     drv_ctx.op_buf_map_info[index].base_address);
   6602                             munmap (drv_ctx.op_buf_map_info[index].base_address,
   6603                                     drv_ctx.op_buf_map_info[index].map_size);
   6604                         }
   6605                         close (drv_ctx.ptr_outputbuffer[index].pmem_fd);
   6606                         drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   6607 #ifdef USE_ION
   6608                         free_ion_memory(&drv_ctx.op_buf_ion_info[index]);
   6609 #endif
   6610                     } else {
   6611                         drv_ctx.op_buf_ion_info[index].ion_device_fd = -1;
   6612                         drv_ctx.op_buf_ion_info[index].ion_alloc_data.handle = 0;
   6613                         drv_ctx.op_buf_ion_info[index].fd_ion_data.fd = -1;
   6614                     }
   6615                     drv_ctx.op_buf_map_info[index].free_buffer = false;
   6616                     drv_ctx.op_buf_map_info[index].base_address = NULL;
   6617                     drv_ctx.op_buf_map_info[index].map_size = 0;
   6618                     drv_ctx.op_buf_map_info[index].offset = 0;
   6619                 }
   6620 #ifdef _ANDROID_
   6621             }
   6622 #endif
   6623         } //!dynamic_buf_mode
   6624         if (release_output_done()) {
   6625             free_extradata();
   6626         }
   6627     }
   6628 
   6629     return OMX_ErrorNone;
   6630 
   6631 }
   6632 
   6633 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   6634         OMX_BUFFERHEADERTYPE **bufferHdr,
   6635         OMX_U32              port,
   6636         OMX_PTR              appData,
   6637         OMX_U32              bytes)
   6638 {
   6639     OMX_BUFFERHEADERTYPE *input = NULL;
   6640     unsigned char *buf_addr = NULL;
   6641     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6642     unsigned   i = 0;
   6643 
   6644     /* Sanity Check*/
   6645     if (bufferHdr == NULL) {
   6646         return OMX_ErrorBadParameter;
   6647     }
   6648 
   6649     if (m_inp_heap_ptr == NULL) {
   6650         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   6651                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   6652                          drv_ctx.ip_buf.actualcount);
   6653         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   6654                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   6655                           drv_ctx.ip_buf.actualcount);
   6656 
   6657         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
   6658             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
   6659             return OMX_ErrorInsufficientResources;
   6660         }
   6661     }
   6662 
   6663     /*Find a Free index*/
   6664     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6665         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
   6666             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6667             break;
   6668         }
   6669     }
   6670 
   6671     if (i < drv_ctx.ip_buf.actualcount) {
   6672         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   6673 
   6674         if (buf_addr == NULL) {
   6675             return OMX_ErrorInsufficientResources;
   6676         }
   6677 
   6678         *bufferHdr = (m_inp_heap_ptr + i);
   6679         input = *bufferHdr;
   6680         BITMASK_SET(&m_heap_inp_bm_count,i);
   6681 
   6682         input->pBuffer           = (OMX_U8 *)buf_addr;
   6683         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6684         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6685         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6686         input->pAppPrivate       = appData;
   6687         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6688         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
   6689         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   6690         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   6691         /*Add the Buffers to freeq*/
   6692         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
   6693                     (unsigned)NULL, (unsigned)NULL)) {
   6694             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   6695             return OMX_ErrorInsufficientResources;
   6696         }
   6697     } else {
   6698         return OMX_ErrorBadParameter;
   6699     }
   6700 
   6701     return eRet;
   6702 
   6703 }
   6704 
   6705 
   6706 /* ======================================================================
   6707    FUNCTION
   6708    omx_vdec::AllocateInputBuffer
   6709 
   6710    DESCRIPTION
   6711    Helper function for allocate buffer in the input pin
   6712 
   6713    PARAMETERS
   6714    None.
   6715 
   6716    RETURN VALUE
   6717    true/false
   6718 
   6719    ========================================================================== */
   6720 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   6721         OMX_IN OMX_HANDLETYPE            hComp,
   6722         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6723         OMX_IN OMX_U32                   port,
   6724         OMX_IN OMX_PTR                   appData,
   6725         OMX_IN OMX_U32                   bytes)
   6726 {
   6727     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6728     struct vdec_setbuffer_cmd setbuffers;
   6729     OMX_BUFFERHEADERTYPE *input = NULL;
   6730     unsigned   i = 0;
   6731     unsigned char *buf_addr = NULL;
   6732     int pmem_fd = -1, ret = 0;
   6733 
   6734     (void) hComp;
   6735     (void) port;
   6736 
   6737 
   6738     if (bytes != drv_ctx.ip_buf.buffer_size) {
   6739         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
   6740                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
   6741         return OMX_ErrorBadParameter;
   6742     }
   6743 
   6744     if (!m_inp_mem_ptr) {
   6745         struct v4l2_requestbuffers bufreq;
   6746         bufreq.memory = V4L2_MEMORY_USERPTR;
   6747         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6748         bufreq.count = drv_ctx.ip_buf.actualcount;
   6749         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   6750         if (ret) {
   6751             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %s", strerror(errno));
   6752             /*TODO: How to handle this case */
   6753             eRet = OMX_ErrorInsufficientResources;
   6754         } else if (bufreq.count != drv_ctx.ip_buf.actualcount) {
   6755             DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d",
   6756                 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count);
   6757             eRet = OMX_ErrorInsufficientResources;
   6758         }
   6759 
   6760         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
   6761                 drv_ctx.ip_buf.actualcount,
   6762                 (unsigned int)drv_ctx.ip_buf.buffer_size);
   6763 
   6764         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   6765                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   6766 
   6767         if (m_inp_mem_ptr == NULL) {
   6768             return OMX_ErrorInsufficientResources;
   6769         }
   6770 
   6771         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   6772                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   6773 
   6774         if (drv_ctx.ptr_inputbuffer == NULL) {
   6775             return OMX_ErrorInsufficientResources;
   6776         }
   6777 #ifdef USE_ION
   6778         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   6779                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   6780 
   6781         if (drv_ctx.ip_buf_ion_info == NULL) {
   6782             return OMX_ErrorInsufficientResources;
   6783         }
   6784 #endif
   6785 
   6786         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   6787             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   6788 #ifdef USE_ION
   6789             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   6790 #endif
   6791         }
   6792     }
   6793 
   6794     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6795         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6796             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6797             break;
   6798         }
   6799     }
   6800 
   6801     if (i < drv_ctx.ip_buf.actualcount) {
   6802         struct v4l2_buffer buf;
   6803         struct v4l2_plane plane;
   6804         int rc;
   6805         DEBUG_PRINT_LOW("Allocate input Buffer");
   6806 #ifdef USE_ION
   6807         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   6808                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   6809                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   6810                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
   6811                 SECURE_FLAGS_INPUT_BUFFER : 0);
   6812         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   6813             return OMX_ErrorInsufficientResources;
   6814         }
   6815         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   6816 #else
   6817         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6818 
   6819         if (pmem_fd < 0) {
   6820             DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6821             return OMX_ErrorInsufficientResources;
   6822         }
   6823 
   6824         if (pmem_fd == 0) {
   6825             pmem_fd = open (MEM_DEVICE,O_RDWR);
   6826 
   6827             if (pmem_fd < 0) {
   6828                 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6829                 return OMX_ErrorInsufficientResources;
   6830             }
   6831         }
   6832 
   6833         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   6834                     drv_ctx.ip_buf.alignment)) {
   6835             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6836             close(pmem_fd);
   6837             return OMX_ErrorInsufficientResources;
   6838         }
   6839 #endif
   6840         if (!secure_mode) {
   6841             buf_addr = (unsigned char *)mmap(NULL,
   6842                     drv_ctx.ip_buf.buffer_size,
   6843                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   6844 
   6845             if (buf_addr == MAP_FAILED) {
   6846                 close(pmem_fd);
   6847 #ifdef USE_ION
   6848                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   6849 #endif
   6850                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
   6851                 return OMX_ErrorInsufficientResources;
   6852             }
   6853         }
   6854         *bufferHdr = (m_inp_mem_ptr + i);
   6855         if (secure_mode)
   6856             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   6857         else
   6858             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   6859         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   6860         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   6861         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   6862         drv_ctx.ptr_inputbuffer [i].offset = 0;
   6863 
   6864 
   6865         buf.index = i;
   6866         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6867         buf.memory = V4L2_MEMORY_USERPTR;
   6868         plane.bytesused = 0;
   6869         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   6870         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   6871         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   6872         plane.reserved[1] = 0;
   6873         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   6874         buf.m.planes = &plane;
   6875         buf.length = 1;
   6876 
   6877         DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
   6878                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   6879 
   6880         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6881 
   6882         if (rc) {
   6883             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   6884             /*TODO: How to handle this case */
   6885             return OMX_ErrorInsufficientResources;
   6886         }
   6887 
   6888         input = *bufferHdr;
   6889         BITMASK_SET(&m_inp_bm_count,i);
   6890         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
   6891         if (allocate_native_handle) {
   6892             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
   6893             if (!nh) {
   6894                 DEBUG_PRINT_ERROR("Native handle create failed");
   6895                 return OMX_ErrorInsufficientResources;
   6896             }
   6897             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6898             input->pBuffer = (OMX_U8 *)nh;
   6899         } else if (secure_mode || m_input_pass_buffer_fd) {
   6900             /*Legacy method, pass ion fd stashed directly in pBuffer*/
   6901             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6902         } else {
   6903             input->pBuffer           = (OMX_U8 *)buf_addr;
   6904         }
   6905         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6906         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6907         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6908         input->pAppPrivate       = appData;
   6909         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6910         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   6911 
   6912         if (drv_ctx.disable_dmx) {
   6913             eRet = allocate_desc_buffer(i);
   6914         }
   6915     } else {
   6916         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   6917         eRet = OMX_ErrorInsufficientResources;
   6918     }
   6919     return eRet;
   6920 }
   6921 
   6922 
   6923 /* ======================================================================
   6924    FUNCTION
   6925    omx_vdec::AllocateOutputBuffer
   6926 
   6927    DESCRIPTION
   6928    Helper fn for AllocateBuffer in the output pin
   6929 
   6930    PARAMETERS
   6931    <TBD>.
   6932 
   6933    RETURN VALUE
   6934    OMX Error None if everything went well.
   6935 
   6936    ========================================================================== */
   6937 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   6938         OMX_IN OMX_HANDLETYPE            hComp,
   6939         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6940         OMX_IN OMX_U32                   port,
   6941         OMX_IN OMX_PTR                   appData,
   6942         OMX_IN OMX_U32                   bytes)
   6943 {
   6944     (void)hComp;
   6945     (void)port;
   6946     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6947     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   6948     unsigned                         i= 0; // Temporary counter
   6949     struct vdec_setbuffer_cmd setbuffers;
   6950     int extra_idx = 0;
   6951 #ifdef USE_ION
   6952     int ion_device_fd =-1;
   6953     struct ion_allocation_data ion_alloc_data;
   6954     struct ion_fd_data fd_ion_data;
   6955 #endif
   6956     if (!m_out_mem_ptr) {
   6957         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
   6958                 drv_ctx.op_buf.actualcount,
   6959                 (unsigned int)drv_ctx.op_buf.buffer_size);
   6960         int nBufHdrSize        = 0;
   6961         int nPlatformEntrySize = 0;
   6962         int nPlatformListSize  = 0;
   6963         int nPMEMInfoSize = 0;
   6964 
   6965         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   6966         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   6967         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   6968 
   6969         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
   6970                 drv_ctx.op_buf.actualcount);
   6971         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   6972             sizeof(OMX_BUFFERHEADERTYPE);
   6973 
   6974         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   6975             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   6976         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   6977             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   6978         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   6979             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   6980 
   6981         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   6982                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   6983                 nPMEMInfoSize,
   6984                 nPlatformListSize);
   6985         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
   6986                 drv_ctx.op_buf.actualcount);
   6987         unsigned char *pmem_baseaddress_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {NULL};
   6988         int pmem_fd[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {-1};
   6989         int alloc_size[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {0};
   6990         static const int block_max_size = 128 * 1024 * 1024;
   6991         unsigned int block_buf_count = block_max_size / drv_ctx.op_buf.buffer_size;
   6992         unsigned int last_block_buf_count = 0, block_count = 1;
   6993         if (drv_ctx.op_buf.actualcount <= block_buf_count) {
   6994             block_buf_count = drv_ctx.op_buf.actualcount;
   6995         } else {
   6996             last_block_buf_count = drv_ctx.op_buf.actualcount % block_buf_count;
   6997             block_count = (drv_ctx.op_buf.actualcount + block_buf_count - 1) / block_buf_count;
   6998         }
   6999         unsigned int idx = 0;
   7000         DEBUG_PRINT_LOW("block_count = %d block_buf_count = %d last_block_buf_count = %d",
   7001             block_count, block_buf_count, last_block_buf_count);
   7002 #ifdef USE_ION
   7003         struct vdec_ion op_buf_ion_info_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS];
   7004         int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
   7005         for (; idx < block_count; idx++) {
   7006             int cnt = ((idx == block_count - 1) && last_block_buf_count) ?
   7007                 last_block_buf_count : block_buf_count;
   7008             alloc_size[idx] = drv_ctx.op_buf.buffer_size * cnt;
   7009             // Allocate output buffers as cached to improve performance of software-reading
   7010             // of the YUVs. Output buffers are cache-invalidated in driver.
   7011             // If color-conversion is involved, Only the C2D output buffers are cached, no
   7012             // need to cache the decoder's output buffers
   7013             op_buf_ion_info_temp[idx].ion_device_fd = alloc_map_ion_memory(
   7014                     alloc_size[idx],
   7015                     secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
   7016                     &op_buf_ion_info_temp[idx].ion_alloc_data, &op_buf_ion_info_temp[idx].fd_ion_data,
   7017                     (secure_mode && !secure_scaling_to_non_secure_opb) ?
   7018                     SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
   7019             if (op_buf_ion_info_temp[idx].ion_device_fd < 0) {
   7020                 DEBUG_PRINT_LOW("Failed to allocate chunk %ul size = %d", idx, alloc_size[idx]);
   7021                 break;
   7022             }
   7023             pmem_fd[idx] = op_buf_ion_info_temp[idx].fd_ion_data.fd;
   7024             DEBUG_PRINT_LOW("Allocated chunk %ul fd = %ul size = %d", idx, pmem_fd[idx], alloc_size[idx]);
   7025         }
   7026         if (idx != block_count) {
   7027             for (OMX_U32 i = 0; i < idx; i++) {
   7028                 close(pmem_fd[i]);
   7029                 free_ion_memory(&op_buf_ion_info_temp[i]);
   7030             }
   7031             return OMX_ErrorInsufficientResources;
   7032         }
   7033 
   7034 #else
   7035         for (idx = 0; idx < block_count; idx++) {
   7036             pmem_fd[idx] = open (MEM_DEVICE,O_RDWR);
   7037 
   7038             if (pmem_fd[idx] < 0) {
   7039                 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   7040                         drv_ctx.op_buf.buffer_size);
   7041                 break;
   7042             }
   7043             int cnt = ((idx == block_count - 1) && last_block_buf_count) ?
   7044                 last_block_buf_count : block_buf_count;
   7045             if (!align_pmem_buffers(pmem_fd[idx], drv_ctx.op_buf.buffer_size * cnt,
   7046                         drv_ctx.op_buf.alignment)) {
   7047                 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   7048                 close(pmem_fd[idx]);
   7049                 break;
   7050             }
   7051         }
   7052         if (idx != block_count) {
   7053             for (i = 0; i < idx; i++) {
   7054                 close(pmem_fd[i]);
   7055             }
   7056             return OMX_ErrorInsufficientResources;
   7057         }
   7058 #endif
   7059         if (!secure_mode) {
   7060             idx = 0;
   7061             for (; idx < block_count; idx++) {
   7062                 pmem_baseaddress_temp[idx] = (unsigned char *)mmap(NULL,
   7063                         alloc_size[idx],
   7064                         PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd[idx], 0);
   7065 
   7066                 if (pmem_baseaddress_temp[idx] == MAP_FAILED) {
   7067                     DEBUG_PRINT_ERROR("MMAP failed for Size %u for fd = %d",
   7068                             (unsigned int)alloc_size[idx], pmem_fd[idx]);
   7069                     close(pmem_fd[idx]);
   7070 #ifdef USE_ION
   7071                     free_ion_memory(&op_buf_ion_info_temp[idx]);
   7072 #endif
   7073                     break;
   7074                 }
   7075             }
   7076             if (idx != block_count) {
   7077                 for (i = 0; i < idx; i++) {
   7078                     munmap(pmem_baseaddress_temp[idx], alloc_size[idx]);
   7079                     close(pmem_fd[i]);
   7080 #ifdef USE_ION
   7081                     free_ion_memory(&op_buf_ion_info_temp[i]);
   7082 #endif
   7083                 }
   7084                 return OMX_ErrorInsufficientResources;
   7085             }
   7086         }
   7087         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   7088         // Alloc mem for platform specific info
   7089         char *pPtr=NULL;
   7090         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   7091                 nPMEMInfoSize,1);
   7092         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   7093                        calloc (sizeof(struct vdec_bufferpayload),
   7094                                drv_ctx.op_buf.actualcount);
   7095         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   7096                      calloc (sizeof (struct vdec_output_frameinfo),
   7097                              drv_ctx.op_buf.actualcount);
   7098         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   7099             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
   7100             return OMX_ErrorInsufficientResources;
   7101         }
   7102 
   7103 #ifdef USE_ION
   7104         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   7105                       calloc (sizeof(struct vdec_ion),
   7106                               drv_ctx.op_buf.actualcount);
   7107         if (!drv_ctx.op_buf_ion_info) {
   7108             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   7109             return OMX_ErrorInsufficientResources;
   7110         }
   7111 #endif
   7112         drv_ctx.op_buf_map_info = (struct vdec_ion_map_info *)\
   7113                       calloc (sizeof(struct vdec_ion_map_info),
   7114                               drv_ctx.op_buf.actualcount);
   7115         if (!drv_ctx.op_buf_map_info) {
   7116             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_map_info");
   7117             return OMX_ErrorInsufficientResources;
   7118         }
   7119 
   7120         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   7121                 && drv_ctx.ptr_respbuffer) {
   7122             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   7123                 (drv_ctx.op_buf.buffer_size *
   7124                  drv_ctx.op_buf.actualcount);
   7125             bufHdr          =  m_out_mem_ptr;
   7126             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   7127             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   7128                 (((char *) m_platform_list)  + nPlatformListSize);
   7129             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   7130                 (((char *) m_platform_entry) + nPlatformEntrySize);
   7131             pPlatformList   = m_platform_list;
   7132             pPlatformEntry  = m_platform_entry;
   7133             pPMEMInfo       = m_pmem_info;
   7134 
   7135             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   7136 
   7137             // Settting the entire storage nicely
   7138             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
   7139             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   7140             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   7141                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   7142                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   7143                 // Set the values when we determine the right HxW param
   7144                 bufHdr->nAllocLen          = bytes;
   7145                 bufHdr->nFilledLen         = 0;
   7146                 bufHdr->pAppPrivate        = appData;
   7147                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   7148                 // Platform specific PMEM Information
   7149                 // Initialize the Platform Entry
   7150                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
   7151                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   7152                 pPlatformEntry->entry      = pPMEMInfo;
   7153                 // Initialize the Platform List
   7154                 pPlatformList->nEntries    = 1;
   7155                 pPlatformList->entryList   = pPlatformEntry;
   7156                 // Keep pBuffer NULL till vdec is opened
   7157                 bufHdr->pBuffer            = NULL;
   7158                 bufHdr->nOffset            = 0;
   7159 
   7160                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   7161                 pPMEMInfo->pmem_fd = -1;
   7162                 bufHdr->pPlatformPrivate = pPlatformList;
   7163 
   7164                 int block_idx = i / block_buf_count;
   7165                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd[block_idx];
   7166                 m_pmem_info[i].pmem_fd = pmem_fd[block_idx];
   7167 #ifdef USE_ION
   7168                 drv_ctx.op_buf_ion_info[i].ion_device_fd = op_buf_ion_info_temp[block_idx].ion_device_fd;
   7169                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = op_buf_ion_info_temp[block_idx].ion_alloc_data;
   7170                 drv_ctx.op_buf_ion_info[i].fd_ion_data = op_buf_ion_info_temp[block_idx].fd_ion_data;
   7171 #endif
   7172                 drv_ctx.op_buf_map_info[i].free_buffer = !(i % block_buf_count);
   7173                 drv_ctx.op_buf_map_info[i].base_address = pmem_baseaddress_temp[block_idx];
   7174                 drv_ctx.op_buf_map_info[i].map_size = alloc_size[block_idx];
   7175                 drv_ctx.op_buf_map_info[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count);
   7176 
   7177                 /*Create a mapping between buffers*/
   7178                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   7179                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   7180                                     &drv_ctx.ptr_outputbuffer[i];
   7181                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count);
   7182                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   7183                     pmem_baseaddress_temp[block_idx] + (drv_ctx.op_buf.buffer_size * (i % block_buf_count));
   7184                 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   7185                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   7186                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   7187 
   7188                 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
   7189                         pmem_fd[block_idx], (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
   7190                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   7191                 // Move the buffer and buffer header pointers
   7192                 bufHdr++;
   7193                 pPMEMInfo++;
   7194                 pPlatformEntry++;
   7195                 pPlatformList++;
   7196             }
   7197         } else {
   7198             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   7199                     m_out_mem_ptr, pPtr);
   7200             if (m_out_mem_ptr) {
   7201                 free(m_out_mem_ptr);
   7202                 m_out_mem_ptr = NULL;
   7203             }
   7204             if (pPtr) {
   7205                 free(pPtr);
   7206                 pPtr = NULL;
   7207             }
   7208             if (drv_ctx.ptr_outputbuffer) {
   7209                 free(drv_ctx.ptr_outputbuffer);
   7210                 drv_ctx.ptr_outputbuffer = NULL;
   7211             }
   7212             if (drv_ctx.ptr_respbuffer) {
   7213                 free(drv_ctx.ptr_respbuffer);
   7214                 drv_ctx.ptr_respbuffer = NULL;
   7215             }
   7216 #ifdef USE_ION
   7217             if (drv_ctx.op_buf_ion_info) {
   7218                 DEBUG_PRINT_LOW("Free o/p ion context");
   7219                 free(drv_ctx.op_buf_ion_info);
   7220                 drv_ctx.op_buf_ion_info = NULL;
   7221             }
   7222 #endif
   7223             free(drv_ctx.op_buf_map_info);
   7224             drv_ctx.op_buf_map_info = NULL;
   7225            eRet =  OMX_ErrorInsufficientResources;
   7226         }
   7227         if (eRet == OMX_ErrorNone)
   7228             eRet = allocate_extradata();
   7229     }
   7230 
   7231     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   7232         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   7233             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   7234             break;
   7235         }
   7236     }
   7237 
   7238     if (eRet == OMX_ErrorNone) {
   7239         if (i < drv_ctx.op_buf.actualcount) {
   7240             struct v4l2_buffer buf;
   7241             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   7242             int rc;
   7243             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   7244 
   7245             drv_ctx.ptr_outputbuffer[i].buffer_len =
   7246                 drv_ctx.op_buf.buffer_size;
   7247 
   7248             *bufferHdr = (m_out_mem_ptr + i );
   7249             if (secure_mode) {
   7250 #ifdef USE_ION
   7251                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   7252                     (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   7253 #else
   7254                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   7255 #endif
   7256             }
   7257             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   7258 
   7259             buf.index = i;
   7260             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7261             buf.memory = V4L2_MEMORY_USERPTR;
   7262             plane[0].length = drv_ctx.op_buf.buffer_size;
   7263             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   7264                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   7265 #ifdef USE_ION
   7266             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   7267 #endif
   7268             plane[0].reserved[1] = drv_ctx.op_buf_map_info[i].offset;
   7269             plane[0].data_offset = 0;
   7270             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   7271             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   7272                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   7273                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   7274 #ifdef USE_ION
   7275                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   7276 #endif
   7277                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   7278                 plane[extra_idx].data_offset = 0;
   7279             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   7280                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
   7281                 return OMX_ErrorBadParameter;
   7282             }
   7283             buf.m.planes = plane;
   7284             buf.length = drv_ctx.num_planes;
   7285             DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   7286             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   7287             if (rc) {
   7288                 /*TODO: How to handle this case */
   7289                 return OMX_ErrorInsufficientResources;
   7290             }
   7291 
   7292             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   7293                 enum v4l2_buf_type buf_type;
   7294                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7295                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7296                 if (rc) {
   7297                     return OMX_ErrorInsufficientResources;
   7298                 } else {
   7299                     streaming[CAPTURE_PORT] = true;
   7300                     DEBUG_PRINT_LOW("STREAMON Successful");
   7301                 }
   7302 
   7303                 DEBUG_PRINT_HIGH("Enabling Turbo mode");
   7304                 request_perf_level(VIDC_TURBO);
   7305             }
   7306 
   7307             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   7308             (*bufferHdr)->pAppPrivate = appData;
   7309             BITMASK_SET(&m_out_bm_count,i);
   7310         } else {
   7311             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
   7312             eRet = OMX_ErrorInsufficientResources;
   7313         }
   7314     }
   7315 
   7316     return eRet;
   7317 }
   7318 
   7319 
   7320 // AllocateBuffer  -- API Call
   7321 /* ======================================================================
   7322    FUNCTION
   7323    omx_vdec::AllocateBuffer
   7324 
   7325    DESCRIPTION
   7326    Returns zero if all the buffers released..
   7327 
   7328    PARAMETERS
   7329    None.
   7330 
   7331    RETURN VALUE
   7332    true/false
   7333 
   7334    ========================================================================== */
   7335 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   7336         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   7337         OMX_IN OMX_U32                        port,
   7338         OMX_IN OMX_PTR                     appData,
   7339         OMX_IN OMX_U32                       bytes)
   7340 {
   7341     unsigned i = 0;
   7342     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   7343 
   7344     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
   7345     if (m_state == OMX_StateInvalid) {
   7346         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
   7347         return OMX_ErrorInvalidState;
   7348     }
   7349 
   7350     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   7351         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
   7352         // ensure that use-buffer was never called.
   7353         // Mix-and-match of useBuffer and allocateBuffer is not allowed
   7354         if (m_inp_mem_ptr && input_use_buffer) {
   7355             DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
   7356             return OMX_ErrorUndefined;
   7357         }
   7358         if (arbitrary_bytes) {
   7359             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   7360         } else {
   7361             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   7362         }
   7363     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   7364         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   7365                 appData,bytes);
   7366     } else {
   7367         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   7368         eRet = OMX_ErrorBadPortIndex;
   7369     }
   7370     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   7371     if (eRet == OMX_ErrorNone) {
   7372         if (allocate_done()) {
   7373             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   7374                 // Send the callback now
   7375                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   7376                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   7377                         OMX_COMPONENT_GENERATE_EVENT);
   7378             }
   7379         }
   7380         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   7381             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   7382                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   7383                 post_event(OMX_CommandPortEnable,
   7384                         OMX_CORE_INPUT_PORT_INDEX,
   7385                         OMX_COMPONENT_GENERATE_EVENT);
   7386             }
   7387         }
   7388         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   7389             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   7390                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   7391                 post_event(OMX_CommandPortEnable,
   7392                         OMX_CORE_OUTPUT_PORT_INDEX,
   7393                         OMX_COMPONENT_GENERATE_EVENT);
   7394             }
   7395         }
   7396     }
   7397     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   7398     return eRet;
   7399 }
   7400 
   7401 // Free Buffer - API call
   7402 /* ======================================================================
   7403    FUNCTION
   7404    omx_vdec::FreeBuffer
   7405 
   7406    DESCRIPTION
   7407 
   7408    PARAMETERS
   7409    None.
   7410 
   7411    RETURN VALUE
   7412    true/false
   7413 
   7414    ========================================================================== */
   7415 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   7416         OMX_IN OMX_U32                 port,
   7417         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7418 {
   7419     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7420     unsigned int nPortIndex;
   7421     (void) hComp;
   7422     DEBUG_PRINT_LOW("In for decoder free_buffer");
   7423 
   7424     if (m_state == OMX_StateIdle &&
   7425             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   7426         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   7427     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   7428             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   7429         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   7430     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   7431                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   7432             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   7433              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   7434         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
   7435     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   7436         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
   7437         post_event(OMX_EventError,
   7438                 OMX_ErrorPortUnpopulated,
   7439                 OMX_COMPONENT_GENERATE_EVENT);
   7440 
   7441         return OMX_ErrorIncorrectStateOperation;
   7442     } else if (m_state != OMX_StateInvalid) {
   7443         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
   7444         post_event(OMX_EventError,
   7445                 OMX_ErrorPortUnpopulated,
   7446                 OMX_COMPONENT_GENERATE_EVENT);
   7447     }
   7448 
   7449     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   7450         /*Check if arbitrary bytes*/
   7451         if (!arbitrary_bytes && !input_use_buffer)
   7452             nPortIndex = buffer - m_inp_mem_ptr;
   7453         else
   7454             nPortIndex = buffer - m_inp_heap_ptr;
   7455 
   7456         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
   7457         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
   7458                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   7459             // Clear the bit associated with it.
   7460             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   7461             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   7462             if (input_use_buffer == true) {
   7463 
   7464                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
   7465                 if (m_phdr_pmem_ptr)
   7466                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   7467             } else {
   7468                 if (arbitrary_bytes) {
   7469                     if (m_phdr_pmem_ptr)
   7470                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   7471                     else
   7472                         free_input_buffer(nPortIndex,NULL);
   7473                 } else
   7474                     free_input_buffer(buffer);
   7475             }
   7476             m_inp_bPopulated = OMX_FALSE;
   7477             if(release_input_done())
   7478                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   7479             /*Free the Buffer Header*/
   7480             if (release_input_done()) {
   7481                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
   7482                 free_input_buffer_header();
   7483             }
   7484         } else {
   7485             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
   7486             eRet = OMX_ErrorBadPortIndex;
   7487         }
   7488 
   7489         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   7490                 && release_input_done()) {
   7491             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   7492             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   7493             post_event(OMX_CommandPortDisable,
   7494                     OMX_CORE_INPUT_PORT_INDEX,
   7495                     OMX_COMPONENT_GENERATE_EVENT);
   7496         }
   7497     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   7498         // check if the buffer is valid
   7499         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7500         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7501                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   7502             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
   7503             // Clear the bit associated with it.
   7504             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   7505             m_out_bPopulated = OMX_FALSE;
   7506             client_buffers.free_output_buffer (buffer);
   7507 
   7508             if(release_output_done()) {
   7509                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   7510             }
   7511             if (release_output_done()) {
   7512                 free_output_buffer_header();
   7513             }
   7514         } else {
   7515             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
   7516             eRet = OMX_ErrorBadPortIndex;
   7517         }
   7518         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   7519                 && release_output_done()) {
   7520             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   7521 
   7522             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   7523             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   7524 #ifdef _ANDROID_ICS_
   7525             if (m_enable_android_native_buffers) {
   7526                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   7527                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   7528             }
   7529 #endif
   7530 
   7531             post_event(OMX_CommandPortDisable,
   7532                     OMX_CORE_OUTPUT_PORT_INDEX,
   7533                     OMX_COMPONENT_GENERATE_EVENT);
   7534         }
   7535     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   7536         nPortIndex = buffer - m_client_output_extradata_mem_ptr;
   7537         DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
   7538 
   7539         BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
   7540 
   7541         if (release_output_extradata_done()) {
   7542             free_output_extradata_buffer_header();
   7543         }
   7544     } else {
   7545         eRet = OMX_ErrorBadPortIndex;
   7546     }
   7547     if ((eRet == OMX_ErrorNone) &&
   7548             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   7549         if (release_done()) {
   7550             /*
   7551              * Reset buffer requirements here to ensure setting buffer requirement
   7552              * when component move to executing state from loaded state via idle.
   7553              */
   7554             drv_ctx.op_buf.buffer_size = 0;
   7555             drv_ctx.op_buf.actualcount = 0;
   7556 
   7557             // Send the callback now
   7558             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   7559             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   7560                     OMX_COMPONENT_GENERATE_EVENT);
   7561         }
   7562     }
   7563     return eRet;
   7564 }
   7565 
   7566 
   7567 /* ======================================================================
   7568    FUNCTION
   7569    omx_vdec::EmptyThisBuffer
   7570 
   7571    DESCRIPTION
   7572    This routine is used to push the encoded video frames to
   7573    the video decoder.
   7574 
   7575    PARAMETERS
   7576    None.
   7577 
   7578    RETURN VALUE
   7579    OMX Error None if everything went successful.
   7580 
   7581    ========================================================================== */
   7582 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   7583         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7584 {
   7585     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   7586     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   7587 
   7588     if (m_state != OMX_StateExecuting &&
   7589             m_state != OMX_StatePause &&
   7590             m_state != OMX_StateIdle) {
   7591         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
   7592         return OMX_ErrorInvalidState;
   7593     }
   7594 
   7595     if (buffer == NULL) {
   7596         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   7597         return OMX_ErrorBadParameter;
   7598     }
   7599 
   7600     if (!m_inp_bEnabled) {
   7601         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   7602         return OMX_ErrorIncorrectStateOperation;
   7603     }
   7604 
   7605     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   7606         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
   7607         return OMX_ErrorBadPortIndex;
   7608     }
   7609 
   7610     if (perf_flag) {
   7611         if (!latency) {
   7612             dec_time.stop();
   7613             latency = dec_time.processing_time_us();
   7614             dec_time.start();
   7615         }
   7616     }
   7617 
   7618     if (arbitrary_bytes) {
   7619         nBufferIndex = buffer - m_inp_heap_ptr;
   7620     } else {
   7621         if (input_use_buffer == true) {
   7622             nBufferIndex = buffer - m_inp_heap_ptr;
   7623             if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7624                 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
   7625                 return OMX_ErrorBadParameter;
   7626             }
   7627             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   7628             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   7629             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   7630             buffer = &m_inp_mem_ptr[nBufferIndex];
   7631             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
   7632                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
   7633         } else {
   7634             nBufferIndex = buffer - m_inp_mem_ptr;
   7635         }
   7636     }
   7637 
   7638     if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7639         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   7640         return OMX_ErrorBadParameter;
   7641     }
   7642 
   7643     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7644         codec_config_flag = true;
   7645         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   7646     }
   7647 
   7648     /* The client should not set this when codec is in arbitrary bytes mode */
   7649     if (m_input_pass_buffer_fd) {
   7650         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
   7651     }
   7652 
   7653     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
   7654             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
   7655     if (arbitrary_bytes) {
   7656         post_event ((unsigned long)hComp,(unsigned long)buffer,
   7657                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   7658     } else {
   7659         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
   7660     }
   7661     time_stamp_dts.insert_timestamp(buffer);
   7662     return OMX_ErrorNone;
   7663 }
   7664 
   7665 /* ======================================================================
   7666    FUNCTION
   7667    omx_vdec::empty_this_buffer_proxy
   7668 
   7669    DESCRIPTION
   7670    This routine is used to push the encoded video frames to
   7671    the video decoder.
   7672 
   7673    PARAMETERS
   7674    None.
   7675 
   7676    RETURN VALUE
   7677    OMX Error None if everything went successful.
   7678 
   7679    ========================================================================== */
   7680 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   7681         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7682 {
   7683     VIDC_TRACE_NAME_HIGH("ETB");
   7684     (void) hComp;
   7685     int push_cnt = 0,i=0;
   7686     unsigned nPortIndex = 0;
   7687     OMX_ERRORTYPE ret = OMX_ErrorNone;
   7688     struct vdec_input_frameinfo frameinfo;
   7689     struct vdec_bufferpayload *temp_buffer;
   7690     struct vdec_seqheader seq_header;
   7691     bool port_setting_changed = true;
   7692 
   7693     /*Should we generate a Aync error event*/
   7694     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   7695         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   7696         return OMX_ErrorBadParameter;
   7697     }
   7698 
   7699     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   7700 
   7701     if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
   7702         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   7703                 nPortIndex);
   7704         return OMX_ErrorBadParameter;
   7705     }
   7706 
   7707     pending_input_buffers++;
   7708     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   7709 
   7710     /* return zero length and not an EOS buffer */
   7711     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   7712             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   7713         DEBUG_PRINT_HIGH("return zero legth buffer");
   7714         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7715                 OMX_COMPONENT_GENERATE_EBD);
   7716         return OMX_ErrorNone;
   7717     }
   7718 
   7719     if (input_flush_progress == true) {
   7720         DEBUG_PRINT_LOW("Flush in progress return buffer ");
   7721         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7722                 OMX_COMPONENT_GENERATE_EBD);
   7723         return OMX_ErrorNone;
   7724     }
   7725 
   7726     auto_lock l(buf_lock);
   7727     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   7728 
   7729     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
   7730         return OMX_ErrorBadParameter;
   7731     }
   7732     /* If its first frame, H264 codec and reject is true, then parse the nal
   7733        and get the profile. Based on this, reject the clip playback */
   7734     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   7735             m_reject_avc_1080p_mp) {
   7736         first_frame = 1;
   7737         DEBUG_PRINT_ERROR("Parse nal to get the profile");
   7738         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   7739                 NALU_TYPE_SPS);
   7740         m_profile = h264_parser->get_profile();
   7741         ret = is_video_session_supported();
   7742         if (ret) {
   7743             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   7744             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   7745             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   7746             m_state = OMX_StateInvalid;
   7747             return OMX_ErrorNone;
   7748         }
   7749     }
   7750 
   7751     VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000);
   7752     VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen);
   7753     DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7754     /*for use buffer we need to memcpy the data*/
   7755     temp_buffer->buffer_len = buffer->nFilledLen;
   7756 
   7757     if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
   7758         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   7759             if (arbitrary_bytes) {
   7760                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   7761             } else {
   7762                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   7763                         buffer->nFilledLen);
   7764             }
   7765         } else {
   7766             return OMX_ErrorBadParameter;
   7767         }
   7768 
   7769     }
   7770 
   7771     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   7772     frameinfo.client_data = (void *) buffer;
   7773     frameinfo.datalen = temp_buffer->buffer_len;
   7774     frameinfo.flags = 0;
   7775     frameinfo.offset = buffer->nOffset;
   7776     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   7777     frameinfo.pmem_offset = temp_buffer->offset;
   7778     frameinfo.timestamp = buffer->nTimeStamp;
   7779     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   7780         DEBUG_PRINT_LOW("ETB: dmx enabled");
   7781         if (m_demux_entries == 0) {
   7782             extract_demux_addr_offsets(buffer);
   7783         }
   7784 
   7785         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
   7786         handle_demux_data(buffer);
   7787         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   7788         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   7789     } else {
   7790         frameinfo.desc_addr = NULL;
   7791         frameinfo.desc_size = 0;
   7792     }
   7793     if (!arbitrary_bytes) {
   7794         frameinfo.flags |= buffer->nFlags;
   7795     }
   7796 
   7797 #ifdef _ANDROID_
   7798     if (m_debug_timestamp) {
   7799         if (arbitrary_bytes) {
   7800             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7801             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7802         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7803             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7804             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7805         }
   7806     }
   7807 #endif
   7808 
   7809     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
   7810 
   7811 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7812         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7813         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7814     }
   7815 
   7816     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7817         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
   7818         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   7819         h264_scratch.nFilledLen = 0;
   7820         nal_count = 0;
   7821         look_ahead_nal = false;
   7822         frame_count = 0;
   7823         if (m_frame_parser.mutils)
   7824             m_frame_parser.mutils->initialize_frame_checking_environment();
   7825         m_frame_parser.flush();
   7826         h264_last_au_ts = LLONG_MAX;
   7827         h264_last_au_flags = 0;
   7828         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   7829         m_demux_entries = 0;
   7830     }
   7831     struct v4l2_buffer buf;
   7832     struct v4l2_plane plane;
   7833     memset( (void *)&buf, 0, sizeof(buf));
   7834     memset( (void *)&plane, 0, sizeof(plane));
   7835     int rc;
   7836     unsigned long  print_count;
   7837     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7838         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   7839         DEBUG_PRINT_HIGH("INPUT EOS reached") ;
   7840     }
   7841     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7842     buf.index = nPortIndex;
   7843     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7844     buf.memory = V4L2_MEMORY_USERPTR;
   7845     plane.bytesused = temp_buffer->buffer_len;
   7846     plane.length = drv_ctx.ip_buf.buffer_size;
   7847     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   7848         (unsigned long)temp_buffer->offset;
   7849     plane.reserved[0] = temp_buffer->pmem_fd;
   7850     plane.reserved[1] = temp_buffer->offset;
   7851     plane.data_offset = 0;
   7852     buf.m.planes = &plane;
   7853     buf.length = 1;
   7854     if (frameinfo.timestamp >= LLONG_MAX) {
   7855         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   7856     }
   7857     //assumption is that timestamp is in milliseconds
   7858     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   7859     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   7860     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   7861     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   7862 
   7863     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7864         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
   7865         android_atomic_inc(&m_queued_codec_config_count);
   7866     }
   7867 
   7868     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7869     if (rc) {
   7870         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
   7871         m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
   7872         return OMX_ErrorHardware;
   7873     }
   7874 
   7875     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7876         codec_config_flag = false;
   7877     }
   7878     if (!streaming[OUTPUT_PORT]) {
   7879         enum v4l2_buf_type buf_type;
   7880         int ret,r;
   7881 
   7882         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7883         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   7884         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7885         if (!ret) {
   7886             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
   7887             streaming[OUTPUT_PORT] = true;
   7888         } else if (errno == EBUSY) {
   7889             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
   7890             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7891                     OMX_COMPONENT_GENERATE_EBD);
   7892             return OMX_ErrorInsufficientResources;
   7893         } else {
   7894             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
   7895             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   7896             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7897                     OMX_COMPONENT_GENERATE_EBD);
   7898             return OMX_ErrorBadParameter;
   7899         }
   7900     }
   7901     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
   7902             frameinfo.bufferaddr, (long long)frameinfo.timestamp,
   7903             (unsigned int)frameinfo.datalen);
   7904 
   7905     return ret;
   7906 }
   7907 
   7908 /* ======================================================================
   7909    FUNCTION
   7910    omx_vdec::FillThisBuffer
   7911 
   7912    DESCRIPTION
   7913    IL client uses this method to release the frame buffer
   7914    after displaying them.
   7915 
   7916    PARAMETERS
   7917    None.
   7918 
   7919    RETURN VALUE
   7920    true/false
   7921 
   7922    ========================================================================== */
   7923 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   7924         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7925 {
   7926     if (m_state != OMX_StateExecuting &&
   7927             m_state != OMX_StatePause &&
   7928             m_state != OMX_StateIdle) {
   7929         DEBUG_PRINT_ERROR("FTB in Invalid State");
   7930         return OMX_ErrorInvalidState;
   7931     }
   7932 
   7933     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   7934         DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
   7935         return OMX_ErrorBadPortIndex;
   7936     }
   7937 
   7938     if (!m_out_bEnabled) {
   7939         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   7940         return OMX_ErrorIncorrectStateOperation;
   7941     }
   7942 
   7943     unsigned nPortIndex = 0;
   7944     if (dynamic_buf_mode) {
   7945         private_handle_t *handle = NULL;
   7946         struct VideoDecoderOutputMetaData *meta;
   7947         unsigned int nPortIndex = 0;
   7948 
   7949         if (!buffer || !buffer->pBuffer) {
   7950             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
   7951             return OMX_ErrorBadParameter;
   7952         }
   7953 
   7954         //get the buffer type and fd info
   7955         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   7956         handle = (private_handle_t *)meta->pHandle;
   7957         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
   7958 
   7959         if (!handle) {
   7960             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
   7961             return OMX_ErrorBadParameter;
   7962         }
   7963         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   7964         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7965         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7966             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   7967             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   7968             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   7969 
   7970            //Store private handle from GraphicBuffer
   7971             native_buffer[nPortIndex].privatehandle = handle;
   7972             native_buffer[nPortIndex].nativehandle = handle;
   7973         } else {
   7974             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
   7975             return OMX_ErrorBadParameter;
   7976         }
   7977 
   7978         //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
   7979         //this with a more sane size so that we don't compensate in rest of code
   7980         //We'll restore this size later on, so that it's transparent to client
   7981         buffer->nFilledLen = 0;
   7982         buffer->nAllocLen = handle->size;
   7983 
   7984         if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
   7985             m_is_display_session = true;
   7986         } else {
   7987             m_is_display_session = false;
   7988         }
   7989         DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
   7990 
   7991         drv_ctx.op_buf.buffer_size = handle->size;
   7992     }
   7993 
   7994     nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7995     if (buffer == NULL ||
   7996             (nPortIndex >= drv_ctx.op_buf.actualcount)) {
   7997         DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7998             nPortIndex, drv_ctx.op_buf.actualcount);
   7999         return OMX_ErrorBadParameter;
   8000     }
   8001 
   8002     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   8003     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
   8004     return OMX_ErrorNone;
   8005 }
   8006 /* ======================================================================
   8007    FUNCTION
   8008    omx_vdec::fill_this_buffer_proxy
   8009 
   8010    DESCRIPTION
   8011    IL client uses this method to release the frame buffer
   8012    after displaying them.
   8013 
   8014    PARAMETERS
   8015    None.
   8016 
   8017    RETURN VALUE
   8018    true/false
   8019 
   8020    ========================================================================== */
   8021 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   8022         OMX_IN OMX_HANDLETYPE        hComp,
   8023         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   8024 {
   8025     VIDC_TRACE_NAME_HIGH("FTB");
   8026     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   8027     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   8028     unsigned nPortIndex = 0;
   8029     struct vdec_fillbuffer_cmd fillbuffer;
   8030     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   8031     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   8032 
   8033     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8034 
   8035     if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
   8036         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   8037             nPortIndex, drv_ctx.op_buf.actualcount);
   8038         return OMX_ErrorBadParameter;
   8039     }
   8040 
   8041     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   8042             bufferAdd, bufferAdd->pBuffer);
   8043     /*Return back the output buffer to client*/
   8044     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) {
   8045         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
   8046         buffer->nFilledLen = 0;
   8047         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   8048         return OMX_ErrorNone;
   8049     }
   8050 
   8051     if (dynamic_buf_mode) {
   8052         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   8053         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen;
   8054         buf_ref_add(nPortIndex);
   8055         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen;
   8056     }
   8057 
   8058     pending_output_buffers++;
   8059     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8060     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   8061     if (!buffer) {
   8062        DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
   8063        return OMX_ErrorBadParameter;
   8064     }
   8065     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   8066     if (ptr_respbuffer) {
   8067         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   8068     }
   8069 
   8070     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   8071         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   8072         buffer->nFilledLen = 0;
   8073         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   8074         pending_output_buffers--;
   8075         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8076         return OMX_ErrorBadParameter;
   8077     }
   8078 
   8079     int rc = 0;
   8080     struct v4l2_buffer buf;
   8081     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   8082     memset( (void *)&buf, 0, sizeof(buf));
   8083     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   8084     unsigned int extra_idx = 0;
   8085 
   8086     buf.index = nPortIndex;
   8087     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8088     buf.memory = V4L2_MEMORY_USERPTR;
   8089     plane[0].bytesused = buffer->nFilledLen;
   8090     plane[0].length = buffer->nAllocLen;
   8091     plane[0].m.userptr =
   8092         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   8093         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   8094     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   8095     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   8096     plane[0].data_offset = 0;
   8097     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   8098     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   8099         plane[extra_idx].bytesused = 0;
   8100         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   8101         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   8102 #ifdef USE_ION
   8103         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   8104 #endif
   8105         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   8106         plane[extra_idx].data_offset = 0;
   8107     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   8108         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   8109         return OMX_ErrorBadParameter;
   8110     }
   8111     buf.m.planes = plane;
   8112     buf.length = drv_ctx.num_planes;
   8113     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   8114              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress);
   8115 
   8116     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   8117     if (rc) {
   8118         buffer->nFilledLen = 0;
   8119         DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno));
   8120         m_cb.FillBufferDone(hComp, m_app_data, buffer);
   8121         return OMX_ErrorHardware;
   8122     }
   8123 
   8124     return OMX_ErrorNone;
   8125 }
   8126 
   8127 /* ======================================================================
   8128    FUNCTION
   8129    omx_vdec::SetCallbacks
   8130 
   8131    DESCRIPTION
   8132    Set the callbacks.
   8133 
   8134    PARAMETERS
   8135    None.
   8136 
   8137    RETURN VALUE
   8138    OMX Error None if everything successful.
   8139 
   8140    ========================================================================== */
   8141 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   8142         OMX_IN OMX_CALLBACKTYPE* callbacks,
   8143         OMX_IN OMX_PTR             appData)
   8144 {
   8145     (void) hComp;
   8146     m_cb       = *callbacks;
   8147     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   8148             m_cb.EventHandler,m_cb.FillBufferDone);
   8149     m_app_data =    appData;
   8150     return OMX_ErrorNotImplemented;
   8151 }
   8152 
   8153 /* ======================================================================
   8154    FUNCTION
   8155    omx_vdec::ComponentDeInit
   8156 
   8157    DESCRIPTION
   8158    Destroys the component and release memory allocated to the heap.
   8159 
   8160    PARAMETERS
   8161    <TBD>.
   8162 
   8163    RETURN VALUE
   8164    OMX Error None if everything successful.
   8165 
   8166    ========================================================================== */
   8167 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   8168 {
   8169    (void) hComp;
   8170 
   8171     unsigned i = 0;
   8172     if (OMX_StateLoaded != m_state) {
   8173         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
   8174                 m_state);
   8175         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   8176     } else {
   8177         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
   8178     }
   8179 
   8180     /*Check if the output buffers have to be cleaned up*/
   8181     if (m_out_mem_ptr) {
   8182         DEBUG_PRINT_LOW("Freeing the Output Memory");
   8183         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   8184             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
   8185                 BITMASK_CLEAR(&m_out_bm_count, i);
   8186                 client_buffers.free_output_buffer (&m_out_mem_ptr[i]);
   8187             }
   8188 
   8189             if (release_output_done()) {
   8190                 break;
   8191             }
   8192         }
   8193 #ifdef _ANDROID_ICS_
   8194         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   8195 #endif
   8196     }
   8197 
   8198     /*Check if the input buffers have to be cleaned up*/
   8199     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   8200         DEBUG_PRINT_LOW("Freeing the Input Memory");
   8201         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   8202 
   8203             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
   8204                 BITMASK_CLEAR(&m_inp_bm_count, i);
   8205                 if (m_inp_mem_ptr)
   8206                     free_input_buffer (i,&m_inp_mem_ptr[i]);
   8207                 else
   8208                     free_input_buffer (i,NULL);
   8209             }
   8210 
   8211             if (release_input_done()) {
   8212                 break;
   8213             }
   8214        }
   8215     }
   8216     free_input_buffer_header();
   8217     free_output_buffer_header();
   8218     if (h264_scratch.pBuffer) {
   8219         free(h264_scratch.pBuffer);
   8220         h264_scratch.pBuffer = NULL;
   8221     }
   8222 
   8223     if (h264_parser) {
   8224         delete h264_parser;
   8225         h264_parser = NULL;
   8226     }
   8227 
   8228     if (m_frame_parser.mutils) {
   8229         DEBUG_PRINT_LOW("Free utils parser");
   8230         delete (m_frame_parser.mutils);
   8231         m_frame_parser.mutils = NULL;
   8232     }
   8233 
   8234     if (m_platform_list) {
   8235         free(m_platform_list);
   8236         m_platform_list = NULL;
   8237     }
   8238     if (m_vendor_config.pData) {
   8239         free(m_vendor_config.pData);
   8240         m_vendor_config.pData = NULL;
   8241     }
   8242 
   8243     // Reset counters in mesg queues
   8244     m_ftb_q.m_size=0;
   8245     m_cmd_q.m_size=0;
   8246     m_etb_q.m_size=0;
   8247     m_ftb_q.m_read = m_ftb_q.m_write =0;
   8248     m_cmd_q.m_read = m_cmd_q.m_write =0;
   8249     m_etb_q.m_read = m_etb_q.m_write =0;
   8250 #ifdef _ANDROID_
   8251     if (m_debug_timestamp) {
   8252         m_timestamp_list.reset_ts_list();
   8253     }
   8254 #endif
   8255 
   8256     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
   8257     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   8258     // NULL);
   8259     DEBUG_PRINT_HIGH("Close the driver instance");
   8260 
   8261     if (m_debug.infile) {
   8262         fclose(m_debug.infile);
   8263         m_debug.infile = NULL;
   8264     }
   8265     if (m_debug.outfile) {
   8266         fclose(m_debug.outfile);
   8267         m_debug.outfile = NULL;
   8268     }
   8269     if (m_debug.out_ymeta_file) {
   8270         fclose(m_debug.out_ymeta_file);
   8271         m_debug.out_ymeta_file = NULL;
   8272     }
   8273     if (m_debug.out_uvmeta_file) {
   8274         fclose(m_debug.out_uvmeta_file);
   8275         m_debug.out_uvmeta_file = NULL;
   8276     }
   8277 #ifdef OUTPUT_EXTRADATA_LOG
   8278     if (outputExtradataFile)
   8279         fclose (outputExtradataFile);
   8280 #endif
   8281     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
   8282     return OMX_ErrorNone;
   8283 }
   8284 
   8285 /* ======================================================================
   8286    FUNCTION
   8287    omx_vdec::UseEGLImage
   8288 
   8289    DESCRIPTION
   8290    OMX Use EGL Image method implementation <TBD>.
   8291 
   8292    PARAMETERS
   8293    <TBD>.
   8294 
   8295    RETURN VALUE
   8296    Not Implemented error.
   8297 
   8298    ========================================================================== */
   8299 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
   8300         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   8301         OMX_IN OMX_U32                        port,
   8302         OMX_IN OMX_PTR                     appData,
   8303         OMX_IN void*                      eglImage)
   8304 {
   8305     (void) appData;
   8306     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   8307     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   8308     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   8309 
   8310 #ifdef USE_EGL_IMAGE_GPU
   8311     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   8312     EGLint fd = -1, offset = 0,pmemPtr = 0;
   8313 #else
   8314     int fd = -1, offset = 0;
   8315 #endif
   8316     DEBUG_PRINT_HIGH("use EGL image support for decoder");
   8317     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   8318         DEBUG_PRINT_ERROR("Invalid EGL image");
   8319     }
   8320 #ifdef USE_EGL_IMAGE_GPU
   8321     if (m_display_id == NULL) {
   8322         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
   8323         return OMX_ErrorInsufficientResources;
   8324     }
   8325     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   8326         eglGetProcAddress("eglQueryImageKHR");
   8327     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
   8328     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
   8329     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
   8330 #else //with OMX test app
   8331     struct temp_egl {
   8332         int pmem_fd;
   8333         int offset;
   8334     };
   8335     struct temp_egl *temp_egl_id = NULL;
   8336     void * pmemPtr = (void *) eglImage;
   8337     temp_egl_id = (struct temp_egl *)eglImage;
   8338     if (temp_egl_id != NULL) {
   8339         fd = temp_egl_id->pmem_fd;
   8340         offset = temp_egl_id->offset;
   8341     }
   8342 #endif
   8343     if (fd < 0) {
   8344         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
   8345         return OMX_ErrorInsufficientResources;
   8346     }
   8347     pmem_info.pmem_fd = (OMX_U32) fd;
   8348     pmem_info.offset = (OMX_U32) offset;
   8349     pmem_entry.entry = (void *) &pmem_info;
   8350     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   8351     pmem_list.entryList = &pmem_entry;
   8352     pmem_list.nEntries = 1;
   8353     ouput_egl_buffers = true;
   8354     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   8355                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   8356                 (OMX_U8 *)pmemPtr)) {
   8357         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
   8358         return OMX_ErrorInsufficientResources;
   8359     }
   8360     return OMX_ErrorNone;
   8361 }
   8362 
   8363 /* ======================================================================
   8364    FUNCTION
   8365    omx_vdec::ComponentRoleEnum
   8366 
   8367    DESCRIPTION
   8368    OMX Component Role Enum method implementation.
   8369 
   8370    PARAMETERS
   8371    <TBD>.
   8372 
   8373    RETURN VALUE
   8374    OMX Error None if everything is successful.
   8375    ========================================================================== */
   8376 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   8377         OMX_OUT OMX_U8*        role,
   8378         OMX_IN OMX_U32        index)
   8379 {
   8380     (void) hComp;
   8381     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8382 
   8383     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   8384         if ((0 == index) && role) {
   8385             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   8386             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8387         } else {
   8388             eRet = OMX_ErrorNoMore;
   8389         }
   8390     }
   8391     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   8392         if ((0 == index) && role) {
   8393             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   8394             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8395         } else {
   8396             eRet = OMX_ErrorNoMore;
   8397         }
   8398     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   8399         if ((0 == index) && role) {
   8400             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   8401             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8402         } else {
   8403             DEBUG_PRINT_LOW("No more roles");
   8404             eRet = OMX_ErrorNoMore;
   8405         }
   8406     }
   8407 
   8408     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   8409             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) {
   8410         if ((0 == index) && role) {
   8411             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   8412             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8413         } else {
   8414             DEBUG_PRINT_LOW("No more roles");
   8415             eRet = OMX_ErrorNoMore;
   8416         }
   8417     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   8418         if ((0 == index) && role) {
   8419             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   8420             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8421         } else {
   8422             DEBUG_PRINT_LOW("No more roles");
   8423             eRet = OMX_ErrorNoMore;
   8424         }
   8425     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   8426         if ((0 == index) && role) {
   8427             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   8428             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8429         } else {
   8430             DEBUG_PRINT_LOW("No more roles");
   8431             eRet = OMX_ErrorNoMore;
   8432         }
   8433     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   8434         if ((0 == index) && role) {
   8435             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   8436             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   8437         } else {
   8438             DEBUG_PRINT_LOW("No more roles");
   8439             eRet = OMX_ErrorNoMore;
   8440         }
   8441     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   8442             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   8443           ) {
   8444         if ((0 == index) && role) {
   8445             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   8446             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8447         } else {
   8448             DEBUG_PRINT_LOW("No more roles");
   8449             eRet = OMX_ErrorNoMore;
   8450         }
   8451     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   8452         if ((0 == index) && role) {
   8453             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   8454             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8455         } else {
   8456             DEBUG_PRINT_LOW("No more roles");
   8457             eRet = OMX_ErrorNoMore;
   8458         }
   8459     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   8460         if ((0 == index) && role) {
   8461             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   8462             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8463         } else {
   8464             DEBUG_PRINT_LOW("No more roles");
   8465             eRet = OMX_ErrorNoMore;
   8466         }
   8467     } else {
   8468         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
   8469         eRet = OMX_ErrorInvalidComponentName;
   8470     }
   8471     return eRet;
   8472 }
   8473 
   8474 
   8475 
   8476 
   8477 /* ======================================================================
   8478    FUNCTION
   8479    omx_vdec::AllocateDone
   8480 
   8481    DESCRIPTION
   8482    Checks if entire buffer pool is allocated by IL Client or not.
   8483    Need this to move to IDLE state.
   8484 
   8485    PARAMETERS
   8486    None.
   8487 
   8488    RETURN VALUE
   8489    true/false.
   8490 
   8491    ========================================================================== */
   8492 bool omx_vdec::allocate_done(void)
   8493 {
   8494     bool bRet = false;
   8495     bool bRet_In = false;
   8496     bool bRet_Out = false;
   8497     bool bRet_Out_Extra = false;
   8498 
   8499     bRet_In = allocate_input_done();
   8500     bRet_Out = allocate_output_done();
   8501     bRet_Out_Extra = allocate_output_extradata_done();
   8502 
   8503     if (bRet_In && bRet_Out && bRet_Out_Extra) {
   8504         bRet = true;
   8505     }
   8506 
   8507     return bRet;
   8508 }
   8509 /* ======================================================================
   8510    FUNCTION
   8511    omx_vdec::AllocateInputDone
   8512 
   8513    DESCRIPTION
   8514    Checks if I/P buffer pool is allocated by IL Client or not.
   8515 
   8516    PARAMETERS
   8517    None.
   8518 
   8519    RETURN VALUE
   8520    true/false.
   8521 
   8522    ========================================================================== */
   8523 bool omx_vdec::allocate_input_done(void)
   8524 {
   8525     bool bRet = false;
   8526     unsigned i=0;
   8527 
   8528     if (m_inp_mem_ptr == NULL) {
   8529         return bRet;
   8530     }
   8531     if (m_inp_mem_ptr ) {
   8532         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   8533             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   8534                 break;
   8535             }
   8536         }
   8537     }
   8538     if (i == drv_ctx.ip_buf.actualcount) {
   8539         bRet = true;
   8540         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   8541     }
   8542     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   8543         m_inp_bPopulated = OMX_TRUE;
   8544     }
   8545     return bRet;
   8546 }
   8547 /* ======================================================================
   8548    FUNCTION
   8549    omx_vdec::AllocateOutputDone
   8550 
   8551    DESCRIPTION
   8552    Checks if entire O/P buffer pool is allocated by IL Client or not.
   8553 
   8554    PARAMETERS
   8555    None.
   8556 
   8557    RETURN VALUE
   8558    true/false.
   8559 
   8560    ========================================================================== */
   8561 bool omx_vdec::allocate_output_done(void)
   8562 {
   8563     bool bRet = false;
   8564     unsigned j=0;
   8565 
   8566     if (m_out_mem_ptr == NULL) {
   8567         return bRet;
   8568     }
   8569 
   8570     if (m_out_mem_ptr) {
   8571         for (; j < drv_ctx.op_buf.actualcount; j++) {
   8572             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   8573                 break;
   8574             }
   8575         }
   8576     }
   8577 
   8578     if (j == drv_ctx.op_buf.actualcount) {
   8579         bRet = true;
   8580         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   8581         if (m_out_bEnabled)
   8582             m_out_bPopulated = OMX_TRUE;
   8583     }
   8584 
   8585     return bRet;
   8586 }
   8587 
   8588 bool omx_vdec::allocate_output_extradata_done(void) {
   8589     bool bRet = false;
   8590     unsigned j=0;
   8591     unsigned nBufferCount = 0;
   8592 
   8593     nBufferCount = m_client_out_extradata_info.getBufferCount();
   8594 
   8595     if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
   8596         return true;
   8597     }
   8598 
   8599     if (m_client_output_extradata_mem_ptr) {
   8600         for (; j < nBufferCount; j++) {
   8601             if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
   8602                 break;
   8603             }
   8604         }
   8605 
   8606         if (j == nBufferCount) {
   8607             bRet = true;
   8608             DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
   8609         }
   8610     }
   8611 
   8612     return bRet;
   8613 }
   8614 /* ======================================================================
   8615    FUNCTION
   8616    omx_vdec::ReleaseDone
   8617 
   8618    DESCRIPTION
   8619    Checks if IL client has released all the buffers.
   8620 
   8621    PARAMETERS
   8622    None.
   8623 
   8624    RETURN VALUE
   8625    true/false
   8626 
   8627    ========================================================================== */
   8628 bool omx_vdec::release_done(void)
   8629 {
   8630     bool bRet = false;
   8631 
   8632     if (release_input_done()) {
   8633         if (release_output_done()) {
   8634             if (release_output_extradata_done()) {
   8635                 bRet = true;
   8636             }
   8637         }
   8638     }
   8639     return bRet;
   8640 }
   8641 
   8642 
   8643 /* ======================================================================
   8644    FUNCTION
   8645    omx_vdec::ReleaseOutputDone
   8646 
   8647    DESCRIPTION
   8648    Checks if IL client has released all the buffers.
   8649 
   8650    PARAMETERS
   8651    None.
   8652 
   8653    RETURN VALUE
   8654    true/false
   8655 
   8656    ========================================================================== */
   8657 bool omx_vdec::release_output_done(void)
   8658 {
   8659     bool bRet = false;
   8660     unsigned i=0,j=0;
   8661 
   8662     DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr);
   8663     if (m_out_mem_ptr) {
   8664         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   8665             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   8666                 break;
   8667             }
   8668         }
   8669         if (j == drv_ctx.op_buf.actualcount) {
   8670             m_out_bm_count = 0;
   8671             bRet = true;
   8672         }
   8673     } else {
   8674         m_out_bm_count = 0;
   8675         bRet = true;
   8676     }
   8677     return bRet;
   8678 }
   8679 /* ======================================================================
   8680    FUNCTION
   8681    omx_vdec::ReleaseInputDone
   8682 
   8683    DESCRIPTION
   8684    Checks if IL client has released all the buffers.
   8685 
   8686    PARAMETERS
   8687    None.
   8688 
   8689    RETURN VALUE
   8690    true/false
   8691 
   8692    ========================================================================== */
   8693 bool omx_vdec::release_input_done(void)
   8694 {
   8695     bool bRet = false;
   8696     unsigned i=0,j=0;
   8697 
   8698     DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   8699     if (m_inp_mem_ptr) {
   8700         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   8701             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   8702                 break;
   8703             }
   8704         }
   8705         if (j==drv_ctx.ip_buf.actualcount) {
   8706             bRet = true;
   8707         }
   8708     } else {
   8709         bRet = true;
   8710     }
   8711     return bRet;
   8712 }
   8713 
   8714 bool omx_vdec::release_output_extradata_done(void) {
   8715     bool bRet = false;
   8716     unsigned i=0,j=0, buffer_count=0;
   8717 
   8718     buffer_count = m_client_out_extradata_info.getBufferCount();
   8719     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
   8720             m_client_output_extradata_mem_ptr, buffer_count);
   8721 
   8722     if (m_client_output_extradata_mem_ptr) {
   8723         for (; j<buffer_count; j++) {
   8724             if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
   8725                 break;
   8726             }
   8727         }
   8728         if (j == buffer_count) {
   8729             bRet = true;
   8730         }
   8731     } else {
   8732         bRet = true;
   8733     }
   8734     return bRet;
   8735 }
   8736 
   8737 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   8738         OMX_BUFFERHEADERTYPE * buffer)
   8739 {
   8740     VIDC_TRACE_NAME_HIGH("FBD");
   8741     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   8742     if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
   8743         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
   8744         return OMX_ErrorBadParameter;
   8745     } else if (output_flush_progress) {
   8746         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   8747         buffer->nFilledLen = 0;
   8748         buffer->nTimeStamp = 0;
   8749         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   8750         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8751         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   8752     }
   8753 
   8754     if (m_debug_extradata) {
   8755         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   8756             DEBUG_PRINT_HIGH("***************************************************");
   8757             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   8758             DEBUG_PRINT_HIGH("***************************************************");
   8759         }
   8760 
   8761         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   8762             DEBUG_PRINT_HIGH("***************************************************");
   8763             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   8764             DEBUG_PRINT_HIGH("***************************************************");
   8765         }
   8766     }
   8767 
   8768 
   8769     DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld",
   8770             buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp);
   8771     pending_output_buffers --;
   8772     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8773 
   8774     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8775         DEBUG_PRINT_HIGH("Output EOS has been reached");
   8776         if (!output_flush_progress)
   8777             post_event((unsigned)NULL, (unsigned)NULL,
   8778                     OMX_COMPONENT_GENERATE_EOS_DONE);
   8779 
   8780         if (psource_frame) {
   8781             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   8782             psource_frame = NULL;
   8783         }
   8784         if (pdest_frame) {
   8785             pdest_frame->nFilledLen = 0;
   8786             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
   8787                     (unsigned)NULL);
   8788             pdest_frame = NULL;
   8789         }
   8790     }
   8791 
   8792 #ifdef OUTPUT_EXTRADATA_LOG
   8793     if (outputExtradataFile) {
   8794         int buf_index = buffer - m_out_mem_ptr;
   8795         OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
   8796 
   8797         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   8798         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   8799             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
   8800 
   8801         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
   8802             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
   8803                                     p_extra->nSize, p_extra->eType);
   8804             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   8805 
   8806             if (p_extra->eType == OMX_ExtraDataNone) {
   8807                 break;
   8808             }
   8809             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   8810         }
   8811     }
   8812 #endif
   8813 
   8814     /* For use buffer we need to copy the data */
   8815     if (!output_flush_progress) {
   8816         /* This is the error check for non-recoverable errros */
   8817         bool is_duplicate_ts_valid = true;
   8818         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   8819 
   8820         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   8821                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   8822                 output_capability == V4L2_PIX_FMT_DIVX ||
   8823                 output_capability == V4L2_PIX_FMT_DIVX_311)
   8824             is_duplicate_ts_valid = false;
   8825 
   8826         if ((output_capability == V4L2_PIX_FMT_H264 ||
   8827                 output_capability == V4L2_PIX_FMT_H264_MVC) &&
   8828                 is_interlaced) {
   8829             if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
   8830                 is_interlaced = false;
   8831             }
   8832         }
   8833 
   8834         if (buffer->nFilledLen > 0) {
   8835             time_stamp_dts.get_next_timestamp(buffer,
   8836                     is_interlaced && is_duplicate_ts_valid);
   8837             if (m_debug_timestamp) {
   8838                 {
   8839                     OMX_TICKS expected_ts = 0;
   8840                     m_timestamp_list.pop_min_ts(expected_ts);
   8841                     if (is_interlaced && is_duplicate_ts_valid) {
   8842                         m_timestamp_list.pop_min_ts(expected_ts);
   8843                     }
   8844                     DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   8845                             buffer->nTimeStamp, expected_ts);
   8846 
   8847                     if (buffer->nTimeStamp != expected_ts) {
   8848                         DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
   8849                     }
   8850                 }
   8851             }
   8852         }
   8853     }
   8854     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
   8855 
   8856     if (m_cb.FillBufferDone) {
   8857         if (buffer->nFilledLen > 0) {
   8858             if (arbitrary_bytes)
   8859                 adjust_timestamp(buffer->nTimeStamp);
   8860             else
   8861                 set_frame_rate(buffer->nTimeStamp);
   8862 
   8863             proc_frms++;
   8864             if (perf_flag) {
   8865                 if (1 == proc_frms) {
   8866                     dec_time.stop();
   8867                     latency = dec_time.processing_time_us() - latency;
   8868                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   8869                     dec_time.start();
   8870                     fps_metrics.start();
   8871                 }
   8872                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8873                     OMX_U64 proc_time = 0;
   8874                     fps_metrics.stop();
   8875                     proc_time = fps_metrics.processing_time_us();
   8876                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
   8877                             (unsigned int)proc_frms, (float)proc_time / 1e6,
   8878                             (float)(1e6 * proc_frms) / proc_time);
   8879                 }
   8880             }
   8881         }
   8882         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8883             prev_ts = LLONG_MAX;
   8884             rst_prev_ts = true;
   8885             proc_frms = 0;
   8886         }
   8887 
   8888         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   8889             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   8890              buffer->pPlatformPrivate)->entryList->entry;
   8891         DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   8892         OMX_BUFFERHEADERTYPE *il_buffer;
   8893         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   8894         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
   8895 
   8896         if (il_buffer && m_last_rendered_TS >= 0) {
   8897             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
   8898 
   8899             // Current frame can be send for rendering if
   8900             // (a) current FPS is <=  60
   8901             // (b) is the next frame after the frame with TS 0
   8902             // (c) is the first frame after seek
   8903             // (d) the delta TS b\w two consecutive frames is > 16 ms
   8904             // (e) its TS is equal to previous frame TS
   8905             // (f) if marked EOS
   8906 
   8907             if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
   8908                il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
   8909                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   8910                m_last_rendered_TS = il_buffer->nTimeStamp;
   8911             } else {
   8912                //mark for droping
   8913                buffer->nFilledLen = 0;
   8914             }
   8915 
   8916             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
   8917                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
   8918                               il_buffer->nTimeStamp,ts_delta);
   8919 
   8920             //above code makes sure that delta b\w two consecutive frames is not
   8921             //greater than 16ms, slow-mo feature, so cap fps to max 60
   8922             if (current_framerate > 60 ) {
   8923                 current_framerate = 60;
   8924             }
   8925         }
   8926 
   8927         // add current framerate to gralloc meta data
   8928         if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && m_out_mem_ptr) {
   8929             // If valid fps was received, directly send it to display for the 1st fbd.
   8930             // Otherwise, calculate fps using fbd timestamps
   8931             float refresh_rate = m_fps_prev;
   8932             if (m_fps_received) {
   8933                 if (1 == proc_frms) {
   8934                     refresh_rate = m_fps_received / (float)(1<<16);
   8935                 }
   8936             } else {
   8937                 // check if dynamic refresh rate change feature enabled or not
   8938                 if (m_drc_enable) {
   8939                     // set coarse fps when 2 fbds received and
   8940                     // set fps again when 30 fbds received as it should be
   8941                     // more accurate than the one set when only 2 fbds received.
   8942                     if (2 == proc_frms || 30 == proc_frms) {
   8943                         if (drv_ctx.frame_rate.fps_denominator) {
   8944                             refresh_rate = drv_ctx.frame_rate.fps_numerator /
   8945                                     (float) drv_ctx.frame_rate.fps_denominator;
   8946                         }
   8947                     }
   8948                 } else {
   8949                     // calculate and set refresh rate for every frame from second frame onwards
   8950                     // display will assume the default refresh rate for first frame (which is 60 fps)
   8951                     if (m_fps_prev) {
   8952                         if (drv_ctx.frame_rate.fps_denominator) {
   8953                             refresh_rate = drv_ctx.frame_rate.fps_numerator /
   8954                                     (float) drv_ctx.frame_rate.fps_denominator;
   8955                         }
   8956                     }
   8957                 }
   8958             }
   8959             if (refresh_rate > 60) {
   8960                 refresh_rate = 60;
   8961             }
   8962             DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
   8963             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8964             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8965                          UPDATE_REFRESH_RATE, (void*)&refresh_rate);
   8966             m_fps_prev = refresh_rate;
   8967         }
   8968 
   8969         if (buffer->nFilledLen && m_enable_android_native_buffers && m_out_mem_ptr) {
   8970             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8971             DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
   8972             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8973                                S3D_FORMAT, (void*)&stereo_output_mode);
   8974         }
   8975 
   8976         if (il_buffer) {
   8977             log_output_buffers(il_buffer);
   8978             if (dynamic_buf_mode) {
   8979                 unsigned int nPortIndex = 0;
   8980                 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8981 
   8982                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
   8983                 // to size of the handle. Do it _after_ log_output_buffers which
   8984                 // requires the respective sizes to be accurate.
   8985 
   8986                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   8987                 buffer->nFilledLen = buffer->nFilledLen ?
   8988                         sizeof(struct VideoDecoderOutputMetaData) : 0;
   8989 
   8990                 //Clear graphic buffer handles in dynamic mode
   8991                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
   8992                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   8993                     native_buffer[nPortIndex].privatehandle = NULL;
   8994                     native_buffer[nPortIndex].nativehandle = NULL;
   8995                 } else {
   8996                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
   8997                     return OMX_ErrorBadParameter;
   8998                 }
   8999             }
   9000             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   9001         } else {
   9002             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   9003             return OMX_ErrorBadParameter;
   9004         }
   9005         DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   9006     } else {
   9007         return OMX_ErrorBadParameter;
   9008     }
   9009 
   9010 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   9011     if (m_smoothstreaming_mode && m_out_mem_ptr) {
   9012         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   9013         BufferDim_t dim;
   9014         private_handle_t *private_handle = NULL;
   9015         dim.sliceWidth = framesize.nWidth;
   9016         dim.sliceHeight = framesize.nHeight;
   9017         if (buf_index < drv_ctx.op_buf.actualcount &&
   9018             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   9019             native_buffer[buf_index].privatehandle)
   9020             private_handle = native_buffer[buf_index].privatehandle;
   9021         if (private_handle) {
   9022             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   9023                 dim.sliceWidth, dim.sliceHeight);
   9024             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   9025         }
   9026     }
   9027 #endif
   9028 
   9029     return OMX_ErrorNone;
   9030 }
   9031 
   9032 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   9033         OMX_BUFFERHEADERTYPE* buffer)
   9034 {
   9035     VIDC_TRACE_NAME_HIGH("EBD");
   9036     int nBufferIndex = buffer - m_inp_mem_ptr;
   9037 
   9038     if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
   9039         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
   9040         return OMX_ErrorBadParameter;
   9041     }
   9042 
   9043     DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x",
   9044             buffer, buffer->pBuffer, buffer->nFlags);
   9045     pending_input_buffers--;
   9046     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   9047 
   9048     if (arbitrary_bytes) {
   9049         if (pdest_frame == NULL && input_flush_progress == false) {
   9050             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
   9051             pdest_frame = buffer;
   9052             buffer->nFilledLen = 0;
   9053             buffer->nTimeStamp = LLONG_MAX;
   9054             push_input_buffer (hComp);
   9055         } else {
   9056             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
   9057             buffer->nFilledLen = 0;
   9058             if (!m_input_free_q.insert_entry((unsigned long)buffer,
   9059                         (unsigned)NULL, (unsigned)NULL)) {
   9060                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
   9061             }
   9062         }
   9063     } else if (m_cb.EmptyBufferDone) {
   9064         buffer->nFilledLen = 0;
   9065         if (input_use_buffer == true) {
   9066             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   9067         }
   9068 
   9069         /* Restore the FD that we over-wrote in ETB */
   9070         if (m_input_pass_buffer_fd) {
   9071             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
   9072         }
   9073 
   9074         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   9075     }
   9076     return OMX_ErrorNone;
   9077 }
   9078 
   9079 int omx_vdec::async_message_process (void *context, void* message)
   9080 {
   9081     omx_vdec* omx = NULL;
   9082     struct vdec_msginfo *vdec_msg = NULL;
   9083     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   9084     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   9085     struct v4l2_plane *plane = NULL;
   9086     struct vdec_output_frameinfo *output_respbuf = NULL;
   9087     int rc=1;
   9088     if (context == NULL || message == NULL) {
   9089         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
   9090         return -1;
   9091     }
   9092     vdec_msg = (struct vdec_msginfo *)message;
   9093 
   9094     omx = reinterpret_cast<omx_vdec*>(context);
   9095 
   9096     switch (vdec_msg->msgcode) {
   9097 
   9098         case VDEC_MSG_EVT_HW_ERROR:
   9099             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9100                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9101             break;
   9102 
   9103         case VDEC_MSG_EVT_HW_OVERLOAD:
   9104             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9105                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
   9106             break;
   9107 
   9108         case VDEC_MSG_EVT_HW_UNSUPPORTED:
   9109             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9110                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   9111             break;
   9112 
   9113         case VDEC_MSG_RESP_START_DONE:
   9114             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9115                     OMX_COMPONENT_GENERATE_START_DONE);
   9116             break;
   9117 
   9118         case VDEC_MSG_RESP_STOP_DONE:
   9119             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9120                     OMX_COMPONENT_GENERATE_STOP_DONE);
   9121             break;
   9122 
   9123         case VDEC_MSG_RESP_RESUME_DONE:
   9124             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9125                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   9126             break;
   9127 
   9128         case VDEC_MSG_RESP_PAUSE_DONE:
   9129             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9130                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   9131             break;
   9132 
   9133         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   9134             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9135                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   9136             break;
   9137         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   9138             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9139                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   9140             break;
   9141         case VDEC_MSG_RESP_INPUT_FLUSHED:
   9142         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   9143 
   9144             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   9145                vdec_msg->msgdata.input_frame_clientdata; */
   9146 
   9147             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   9148             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
   9149                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
   9150                 omxhdr = NULL;
   9151                 vdec_msg->status_code = VDEC_S_EFATAL;
   9152                 break;
   9153 
   9154             }
   9155             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
   9156 
   9157             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   9158                 DEBUG_PRINT_HIGH("Unsupported input");
   9159                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9160                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9161             }
   9162             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   9163                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   9164                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   9165             }
   9166             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   9167 
   9168                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
   9169                 android_atomic_dec(&omx->m_queued_codec_config_count);
   9170                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
   9171                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
   9172                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
   9173                     sem_post(&omx->m_safe_flush);
   9174                 }
   9175             }
   9176             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME ||
   9177                 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   9178                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   9179             }
   9180             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
   9181                     OMX_COMPONENT_GENERATE_EBD);
   9182             break;
   9183         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   9184             int64_t *timestamp;
   9185             timestamp = (int64_t *) malloc(sizeof(int64_t));
   9186             if (timestamp) {
   9187                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   9188                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
   9189                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   9190                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
   9191                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
   9192             }
   9193             break;
   9194         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   9195         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   9196 
   9197            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   9198            if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL ||
   9199                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
   9200                omxhdr = NULL;
   9201                vdec_msg->status_code = VDEC_S_EFATAL;
   9202                break;
   9203            }
   9204            plane = v4l2_buf_ptr->m.planes;
   9205            omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index;
   9206 
   9207            if (omxhdr && omxhdr->pOutputPortPrivate &&
   9208                    ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
   9209                    (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   9210                      - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
   9211 
   9212                if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   9213                    omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   9214                    omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   9215                    omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   9216                    omxhdr->nFlags = 0;
   9217 
   9218                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
   9219                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   9220                         //rc = -1;
   9221                    }
   9222                    if (omxhdr->nFilledLen) {
   9223                        omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   9224                    }
   9225                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   9226                        omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   9227                    } else {
   9228                        omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   9229                    }
   9230                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   9231                        omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   9232                    }
   9233                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   9234                        omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   9235                    }
   9236                    if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
   9237                        omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
   9238                    }
   9239                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   9240                         omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
   9241                         DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   9242                                    omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   9243                    }
   9244 
   9245                    if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   9246                            !omx->output_flush_progress &&
   9247                            !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   9248                            !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
   9249                        omx->time_stamp_dts.remove_time_stamp(
   9250                                omxhdr->nTimeStamp,
   9251                                (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   9252                                ?true:false);
   9253 
   9254                        omxhdr->nFilledLen = 0;
   9255                        omx->pending_output_buffers--;
   9256                        omx->post_event ((unsigned long)NULL,(unsigned long)omx->client_buffers.get_il_buf_hdr(omxhdr),
   9257                                OMX_COMPONENT_GENERATE_FTB);
   9258                        break;
   9259                    }
   9260                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   9261                        omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   9262                    }
   9263 
   9264                    output_respbuf = (struct vdec_output_frameinfo *)\
   9265                             omxhdr->pOutputPortPrivate;
   9266                    if (!output_respbuf) {
   9267                      DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
   9268                      return -1;
   9269                    }
   9270                    output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   9271                    output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   9272 
   9273                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   9274                        output_respbuf->pic_type = PICTURE_TYPE_I;
   9275                    }
   9276                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   9277                        output_respbuf->pic_type = PICTURE_TYPE_P;
   9278                    }
   9279                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   9280                        output_respbuf->pic_type = PICTURE_TYPE_B;
   9281                    }
   9282 
   9283                    if (vdec_msg->msgdata.output_frame.len) {
   9284                        if (!omx->output_flush_progress && (omxhdr->nFilledLen > 0)) {
   9285                            // set the default colorspace advised by client, since the bitstream may be
   9286                            // devoid of colorspace-info.
   9287                            if (omx->m_enable_android_native_buffers) {
   9288                                ColorSpace_t color_space = ITU_R_601;
   9289 
   9290                            // Disabled ?
   9291                            // WA for VP8. Vp8 encoder does not embed color-info (yet!).
   9292                            // Encoding RGBA results in 601-LR for all resolutions.
   9293                            // This conflicts with the client't defaults which are based on resolution.
   9294                            //   Eg: 720p will be encoded as 601-LR. Client will say 709.
   9295                            // Re-enable this code once vp8 encoder generates color-info and hence the
   9296                            // decoder will be able to override with the correct source color.
   9297 #if 0
   9298                                switch (omx->m_client_color_space.sAspects.mPrimaries) {
   9299                                    case ColorAspects::PrimariesBT601_6_625:
   9300                                    case ColorAspects::PrimariesBT601_6_525:
   9301                                    {
   9302                                        color_space = omx->m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
   9303                                                ITU_R_601_FR : ITU_R_601;
   9304                                        break;
   9305                                    }
   9306                                    case ColorAspects::PrimariesBT709_5:
   9307                                    {
   9308                                        color_space = ITU_R_709;
   9309                                        break;
   9310                                    }
   9311                                    default:
   9312                                    {
   9313                                        break;
   9314                                    }
   9315                                }
   9316 #endif
   9317                                DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
   9318                                        color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   9319                                omx->set_colorspace_in_handle(color_space, omxhdr - omx->m_out_mem_ptr);
   9320                            }
   9321                        }
   9322 
   9323                        DEBUG_PRINT_LOW("Processing extradata");
   9324                        omx->handle_extradata(omxhdr);
   9325 
   9326                        if (omx->m_extradata_info.output_crop_updated) {
   9327                            DEBUG_PRINT_LOW("Read FBD crop from output extra data");
   9328                            vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
   9329                            vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
   9330                            vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
   9331                            vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
   9332                            vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
   9333                            vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
   9334                        } else {
   9335                            DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
   9336                            vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2];
   9337                            vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3];
   9338                            vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4];
   9339                            vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
   9340                            vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
   9341                            vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
   9342 
   9343                            /* Copy these values back to OMX internal variables to make both handlign same*/
   9344 
   9345                            omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
   9346                            omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top;
   9347                            omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
   9348                            omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
   9349                            omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   9350                            omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   9351                        }
   9352                    }
   9353 
   9354                    vdec_msg->msgdata.output_frame.bufferaddr =
   9355                        omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   9356 
   9357                    if (vdec_msg->msgdata.output_frame.len)
   9358                        memcpy(&omx->drv_ctx.frame_size,
   9359                                &vdec_msg->msgdata.output_frame.framesize,
   9360                                sizeof(struct vdec_framesize));
   9361 
   9362                    DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
   9363                            " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
   9364                            omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
   9365                            omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
   9366                            vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
   9367                            (unsigned int)vdec_msg->msgdata.output_frame.len,
   9368                            vdec_msg->msgdata.output_frame.framesize.left,
   9369                            vdec_msg->msgdata.output_frame.framesize.top,
   9370                            vdec_msg->msgdata.output_frame.framesize.right,
   9371                            vdec_msg->msgdata.output_frame.framesize.bottom);
   9372 
   9373                    /* Post event if resolution OR crop changed */
   9374                    /* filled length will be changed if resolution changed */
   9375                    /* Crop parameters can be changed even without resolution change */
   9376                    if (omxhdr->nFilledLen
   9377                        && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
   9378                        || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
   9379                        || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
   9380                        || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
   9381                        || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
   9382                        || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
   9383                        || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
   9384 
   9385                        DEBUG_PRINT_HIGH("Parameters 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",
   9386                                omx->prev_n_filled_len,
   9387                                omx->drv_ctx.video_resolution.frame_width,
   9388                                omx->drv_ctx.video_resolution.frame_height,
   9389                                omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
   9390                                omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
   9391                                omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
   9392                                vdec_msg->msgdata.output_frame.picsize.frame_height,
   9393                                vdec_msg->msgdata.output_frame.framesize.left,
   9394                                vdec_msg->msgdata.output_frame.framesize.top,
   9395                                vdec_msg->msgdata.output_frame.framesize.right,
   9396                                vdec_msg->msgdata.output_frame.framesize.bottom);
   9397 
   9398                        omx->drv_ctx.video_resolution.frame_width =
   9399                                vdec_msg->msgdata.output_frame.picsize.frame_width;
   9400                        omx->drv_ctx.video_resolution.frame_height =
   9401                                vdec_msg->msgdata.output_frame.picsize.frame_height;
   9402                        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   9403                            omx->drv_ctx.video_resolution.stride =
   9404                                VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
   9405                            omx->drv_ctx.video_resolution.scan_lines =
   9406                                VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
   9407                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   9408                            omx->drv_ctx.video_resolution.stride =
   9409                                VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
   9410                            omx->drv_ctx.video_resolution.scan_lines =
   9411                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
   9412                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   9413                            omx->drv_ctx.video_resolution.stride =
   9414                                VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width);
   9415                            omx->drv_ctx.video_resolution.scan_lines =
   9416                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
   9417                         }
   9418 
   9419                        omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   9420                                 OMX_IndexConfigCommonOutputCrop,
   9421                                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   9422                    }
   9423 
   9424                    if (omxhdr->nFilledLen)
   9425                        omx->prev_n_filled_len = omxhdr->nFilledLen;
   9426 
   9427                    if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) {
   9428                         omx->request_perf_level(VIDC_NOMINAL);
   9429                    }
   9430                    if (omx->output_use_buffer && omxhdr->pBuffer &&
   9431                        vdec_msg->msgdata.output_frame.bufferaddr)
   9432                        memcpy ( omxhdr->pBuffer, (void *)
   9433                                ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   9434                                 (unsigned long)vdec_msg->msgdata.output_frame.offset),
   9435                                vdec_msg->msgdata.output_frame.len);
   9436                } else {
   9437                    DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
   9438                            (unsigned int)vdec_msg->msgdata.output_frame.len,
   9439                            omxhdr->nAllocLen, omx->prev_n_filled_len);
   9440                    omxhdr->nFilledLen = 0;
   9441                }
   9442 
   9443                omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
   9444                         OMX_COMPONENT_GENERATE_FBD);
   9445 
   9446             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
   9447                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
   9448                         OMX_COMPONENT_GENERATE_EOS_DONE);
   9449             } else {
   9450                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   9451                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9452             }
   9453             break;
   9454         case VDEC_MSG_EVT_CONFIG_CHANGED:
   9455             DEBUG_PRINT_HIGH("Port settings changed");
   9456             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   9457             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   9458             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   9459                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   9460             if (!omx->m_need_turbo) {
   9461                 omx->request_perf_level(VIDC_NOMINAL);
   9462             }
   9463             break;
   9464         default:
   9465             break;
   9466     }
   9467     return rc;
   9468 }
   9469 
   9470 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   9471         OMX_HANDLETYPE hComp,
   9472         OMX_BUFFERHEADERTYPE *buffer
   9473         )
   9474 {
   9475     unsigned address,p2,id;
   9476     DEBUG_PRINT_LOW("Empty this arbitrary");
   9477 
   9478     if (buffer == NULL) {
   9479         return OMX_ErrorBadParameter;
   9480     }
   9481     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   9482     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
   9483             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
   9484 
   9485     /* return zero length and not an EOS buffer */
   9486     /* return buffer if input flush in progress */
   9487     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   9488                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   9489         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
   9490         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   9491         return OMX_ErrorNone;
   9492     }
   9493 
   9494     if (psource_frame == NULL) {
   9495         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   9496         psource_frame = buffer;
   9497         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
   9498         push_input_buffer (hComp);
   9499     } else {
   9500         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
   9501         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
   9502                     (unsigned)NULL)) {
   9503             return OMX_ErrorBadParameter;
   9504         }
   9505     }
   9506 
   9507     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   9508         codec_config_flag = false;
   9509     }
   9510     return OMX_ErrorNone;
   9511 }
   9512 
   9513 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   9514 {
   9515     unsigned long address,p2,id;
   9516     OMX_ERRORTYPE ret = OMX_ErrorNone;
   9517 
   9518     if (pdest_frame == NULL || psource_frame == NULL) {
   9519         /*Check if we have a destination buffer*/
   9520         if (pdest_frame == NULL) {
   9521             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
   9522             if (m_input_free_q.m_size) {
   9523                 m_input_free_q.pop_entry(&address,&p2,&id);
   9524                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   9525                 pdest_frame->nFilledLen = 0;
   9526                 pdest_frame->nTimeStamp = LLONG_MAX;
   9527                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
   9528             }
   9529         }
   9530 
   9531         /*Check if we have a destination buffer*/
   9532         if (psource_frame == NULL) {
   9533             DEBUG_PRINT_LOW("Get a source buffer from the queue");
   9534             if (m_input_pending_q.m_size) {
   9535                 m_input_pending_q.pop_entry(&address,&p2,&id);
   9536                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   9537                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   9538                         psource_frame->nTimeStamp);
   9539                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   9540                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9541 
   9542             }
   9543         }
   9544 
   9545     }
   9546 
   9547     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   9548         switch (codec_type_parse) {
   9549             case CODEC_TYPE_MPEG4:
   9550             case CODEC_TYPE_H263:
   9551             case CODEC_TYPE_MPEG2:
   9552                 ret =  push_input_sc_codec(hComp);
   9553                 break;
   9554             case CODEC_TYPE_H264:
   9555                 ret = push_input_h264(hComp);
   9556                 break;
   9557             case CODEC_TYPE_HEVC:
   9558                 ret = push_input_hevc(hComp);
   9559                 break;
   9560             case CODEC_TYPE_VC1:
   9561                 ret = push_input_vc1(hComp);
   9562                 break;
   9563             default:
   9564                 break;
   9565         }
   9566         if (ret != OMX_ErrorNone) {
   9567             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
   9568             omx_report_error ();
   9569             break;
   9570         }
   9571     }
   9572 
   9573     return ret;
   9574 }
   9575 
   9576 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   9577 {
   9578     OMX_U32 partial_frame = 1;
   9579     OMX_BOOL generate_ebd = OMX_TRUE;
   9580     unsigned long address = 0, p2 = 0, id = 0;
   9581 
   9582     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
   9583             psource_frame,psource_frame->nTimeStamp);
   9584     if (m_frame_parser.parse_sc_frame(psource_frame,
   9585                 pdest_frame,&partial_frame) == -1) {
   9586         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9587         return OMX_ErrorBadParameter;
   9588     }
   9589 
   9590     if (partial_frame == 0) {
   9591         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
   9592                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
   9593 
   9594 
   9595         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
   9596         /*First Parsed buffer will have only header Hence skip*/
   9597         if (frame_count == 0) {
   9598             DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
   9599 
   9600             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   9601                     codec_type_parse == CODEC_TYPE_DIVX) {
   9602                 mp4StreamType psBits;
   9603                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   9604                 psBits.numBytes = pdest_frame->nFilledLen;
   9605                 mp4_headerparser.parseHeader(&psBits);
   9606             }
   9607 
   9608             frame_count++;
   9609         } else {
   9610             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9611             if (pdest_frame->nFilledLen) {
   9612                 /*Push the frame to the Decoder*/
   9613                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9614                     return OMX_ErrorBadParameter;
   9615                 }
   9616                 frame_count++;
   9617                 pdest_frame = NULL;
   9618 
   9619                 if (m_input_free_q.m_size) {
   9620                     m_input_free_q.pop_entry(&address,&p2,&id);
   9621                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9622                     pdest_frame->nFilledLen = 0;
   9623                 }
   9624             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   9625                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
   9626                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
   9627                         (unsigned)NULL);
   9628                 pdest_frame = NULL;
   9629             }
   9630         }
   9631     } else {
   9632         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
   9633         /*Check if Destination Buffer is full*/
   9634         if (pdest_frame->nAllocLen ==
   9635                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   9636             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
   9637             return OMX_ErrorStreamCorrupt;
   9638         }
   9639     }
   9640 
   9641     if (psource_frame->nFilledLen == 0) {
   9642         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9643             if (pdest_frame) {
   9644                 pdest_frame->nFlags |= psource_frame->nFlags;
   9645                 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   9646                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
   9647                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9648                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   9649                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   9650                 /*Push the frame to the Decoder*/
   9651                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9652                     return OMX_ErrorBadParameter;
   9653                 }
   9654                 frame_count++;
   9655                 pdest_frame = NULL;
   9656             } else {
   9657                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
   9658                 generate_ebd = OMX_FALSE;
   9659             }
   9660         }
   9661         if (generate_ebd) {
   9662             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
   9663             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9664             psource_frame = NULL;
   9665 
   9666             if (m_input_pending_q.m_size) {
   9667                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9668                 m_input_pending_q.pop_entry(&address,&p2,&id);
   9669                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9670                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   9671                         psource_frame->nTimeStamp);
   9672                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   9673                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9674             }
   9675         }
   9676     }
   9677     return OMX_ErrorNone;
   9678 }
   9679 
   9680 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   9681 {
   9682     OMX_U32 partial_frame = 1;
   9683     unsigned long address = 0, p2 = 0, id = 0;
   9684     OMX_BOOL isNewFrame = OMX_FALSE;
   9685     OMX_BOOL generate_ebd = OMX_TRUE;
   9686 
   9687     if (h264_scratch.pBuffer == NULL) {
   9688         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
   9689         return OMX_ErrorBadParameter;
   9690     }
   9691     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
   9692             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
   9693     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
   9694     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9695         look_ahead_nal = false;
   9696         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9697                 h264_scratch.nFilledLen) {
   9698             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9699                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9700             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9701             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
   9702             h264_scratch.nFilledLen = 0;
   9703         } else {
   9704             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
   9705             return OMX_ErrorBadParameter;
   9706         }
   9707     }
   9708 
   9709     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   9710        in EOS flag getting associated with the destination
   9711     */
   9712     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   9713             pdest_frame->nFilledLen) {
   9714         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   9715         generate_ebd = OMX_FALSE;
   9716     }
   9717 
   9718     if (nal_length == 0) {
   9719         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
   9720         if (m_frame_parser.parse_sc_frame(psource_frame,
   9721                     &h264_scratch,&partial_frame) == -1) {
   9722             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9723             return OMX_ErrorBadParameter;
   9724         }
   9725     } else {
   9726         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   9727         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9728                     &h264_scratch,&partial_frame) == -1) {
   9729             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9730             return OMX_ErrorBadParameter;
   9731         }
   9732     }
   9733 
   9734     if (partial_frame == 0) {
   9735         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9736             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9737             nal_count++;
   9738             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9739             h264_scratch.nFlags = psource_frame->nFlags;
   9740         } else {
   9741             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
   9742             if (h264_scratch.nFilledLen) {
   9743                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   9744                         NALU_TYPE_SPS);
   9745 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9746                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   9747                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9748                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9749                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9750                     // If timeinfo is present frame info from SEI is already processed
   9751                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9752                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9753 #endif
   9754                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9755                 nal_count++;
   9756                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   9757                     pdest_frame->nTimeStamp = h264_last_au_ts;
   9758                     pdest_frame->nFlags = h264_last_au_flags;
   9759 #ifdef PANSCAN_HDLR
   9760                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9761                         h264_parser->update_panscan_data(h264_last_au_ts);
   9762 #endif
   9763                 }
   9764                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   9765                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   9766                     h264_last_au_ts = h264_scratch.nTimeStamp;
   9767                     h264_last_au_flags = h264_scratch.nFlags;
   9768 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9769                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9770                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   9771                         if (!VALID_TS(h264_last_au_ts))
   9772                             h264_last_au_ts = ts_in_sei;
   9773                     }
   9774 #endif
   9775                 } else
   9776                     h264_last_au_ts = LLONG_MAX;
   9777             }
   9778 
   9779             if (!isNewFrame) {
   9780                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9781                         h264_scratch.nFilledLen) {
   9782                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
   9783                             (unsigned int)h264_scratch.nFilledLen);
   9784                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9785                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9786                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9787                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   9788                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   9789                     h264_scratch.nFilledLen = 0;
   9790                 } else {
   9791                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
   9792                     return OMX_ErrorBadParameter;
   9793                 }
   9794             } else if(h264_scratch.nFilledLen) {
   9795                 look_ahead_nal = true;
   9796                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
   9797                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9798                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   9799                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   9800 
   9801                 if (pdest_frame->nFilledLen == 0) {
   9802                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
   9803                     look_ahead_nal = false;
   9804                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9805                             h264_scratch.nFilledLen) {
   9806                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9807                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9808                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9809                         h264_scratch.nFilledLen = 0;
   9810                     } else {
   9811                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
   9812                         return OMX_ErrorBadParameter;
   9813                     }
   9814                 } else {
   9815                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   9816                         DEBUG_PRINT_LOW("Reset the EOS Flag");
   9817                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9818                     }
   9819                     /*Push the frame to the Decoder*/
   9820                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9821                         return OMX_ErrorBadParameter;
   9822                     }
   9823                     //frame_count++;
   9824                     pdest_frame = NULL;
   9825                     if (m_input_free_q.m_size) {
   9826                         m_input_free_q.pop_entry(&address,&p2,&id);
   9827                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9828                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
   9829                         pdest_frame->nFilledLen = 0;
   9830                         pdest_frame->nFlags = 0;
   9831                         pdest_frame->nTimeStamp = LLONG_MAX;
   9832                     }
   9833                 }
   9834             }
   9835         }
   9836     } else {
   9837         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
   9838         /*Check if Destination Buffer is full*/
   9839         if (h264_scratch.nAllocLen ==
   9840                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   9841             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   9842             return OMX_ErrorStreamCorrupt;
   9843         }
   9844     }
   9845 
   9846     if (!psource_frame->nFilledLen) {
   9847         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
   9848 
   9849         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9850             if (pdest_frame) {
   9851                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   9852                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9853                         h264_scratch.nFilledLen) {
   9854                     if(pdest_frame->nFilledLen == 0) {
   9855                         /* No residual frame from before, send whatever
   9856                          * we have left */
   9857                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9858                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   9859                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9860                         h264_scratch.nFilledLen = 0;
   9861                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   9862                     } else {
   9863                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9864                         if(!isNewFrame) {
   9865                             /* Have a residual frame, but we know that the
   9866                              * AU in this frame is belonging to whatever
   9867                              * frame we had left over.  So append it */
   9868                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9869                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9870                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9871                              h264_scratch.nFilledLen = 0;
   9872                              if (h264_last_au_ts != LLONG_MAX)
   9873                                  pdest_frame->nTimeStamp = h264_last_au_ts;
   9874                         } else {
   9875                             /* Completely new frame, let's just push what
   9876                              * we have now.  The resulting EBD would trigger
   9877                              * another push */
   9878                             generate_ebd = OMX_FALSE;
   9879                             pdest_frame->nTimeStamp = h264_last_au_ts;
   9880                             h264_last_au_ts = h264_scratch.nTimeStamp;
   9881                         }
   9882                     }
   9883                 } else {
   9884                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
   9885                     return OMX_ErrorBadParameter;
   9886                 }
   9887 
   9888                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   9889                 if(generate_ebd == OMX_TRUE) {
   9890                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9891                 }
   9892 
   9893                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
   9894                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9895                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
   9896 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9897                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9898                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   9899                     if (!VALID_TS(pdest_frame->nTimeStamp))
   9900                         pdest_frame->nTimeStamp = ts_in_sei;
   9901                 }
   9902 #endif
   9903                 /*Push the frame to the Decoder*/
   9904                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9905                     return OMX_ErrorBadParameter;
   9906                 }
   9907                 frame_count++;
   9908                 pdest_frame = NULL;
   9909             } else {
   9910                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9911                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9912                 generate_ebd = OMX_FALSE;
   9913             }
   9914         }
   9915     }
   9916     if (generate_ebd && !psource_frame->nFilledLen) {
   9917         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9918         psource_frame = NULL;
   9919         if (m_input_pending_q.m_size) {
   9920             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9921             m_input_pending_q.pop_entry(&address,&p2,&id);
   9922             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9923             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
   9924                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9925         }
   9926     }
   9927     return OMX_ErrorNone;
   9928 }
   9929 
   9930 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
   9931 {
   9932     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9933     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
   9934         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
   9935         if (pDst->nTimeStamp == LLONG_MAX) {
   9936             pDst->nTimeStamp = pSrc->nTimeStamp;
   9937             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
   9938         }
   9939         pDst->nFilledLen += pSrc->nFilledLen;
   9940         pSrc->nFilledLen = 0;
   9941     } else {
   9942         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
   9943         rc = OMX_ErrorBadParameter;
   9944     }
   9945     return rc;
   9946 }
   9947 
   9948 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
   9949 {
   9950     OMX_U32 partial_frame = 1;
   9951     unsigned long address,p2,id;
   9952     OMX_BOOL isNewFrame = OMX_FALSE;
   9953     OMX_BOOL generate_ebd = OMX_TRUE;
   9954     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9955     if (h264_scratch.pBuffer == NULL) {
   9956         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
   9957         return OMX_ErrorBadParameter;
   9958     }
   9959 
   9960     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
   9961             pdest_frame nFilledLen %u nTimeStamp %lld",
   9962             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9963 
   9964     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9965         look_ahead_nal = false;
   9966         rc = copy_buffer(pdest_frame, &h264_scratch);
   9967         if (rc != OMX_ErrorNone) {
   9968             return rc;
   9969         }
   9970     }
   9971 
   9972     if (nal_length == 0) {
   9973         if (m_frame_parser.parse_sc_frame(psource_frame,
   9974                     &h264_scratch,&partial_frame) == -1) {
   9975             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9976             return OMX_ErrorBadParameter;
   9977         }
   9978     } else {
   9979         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
   9980         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9981                     &h264_scratch,&partial_frame) == -1) {
   9982             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9983             return OMX_ErrorBadParameter;
   9984         }
   9985     }
   9986 
   9987     if (partial_frame == 0) {
   9988         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9989             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9990             nal_count++;
   9991             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9992             h264_scratch.nFlags = psource_frame->nFlags;
   9993         } else {
   9994             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
   9995             if (h264_scratch.nFilledLen) {
   9996                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
   9997                 nal_count++;
   9998             }
   9999 
   10000             if (!isNewFrame) {
   10001                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
   10002                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
   10003                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
   10004                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   10005                 rc = copy_buffer(pdest_frame, &h264_scratch);
   10006                 if (rc != OMX_ErrorNone) {
   10007                     return rc;
   10008                 }
   10009             } else {
   10010                 look_ahead_nal = true;
   10011                 if (pdest_frame->nFilledLen == 0) {
   10012                     look_ahead_nal = false;
   10013                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
   10014                     rc = copy_buffer(pdest_frame, &h264_scratch);
   10015                     if (rc != OMX_ErrorNone) {
   10016                         return OMX_ErrorBadParameter;
   10017                     }
   10018                 } else {
   10019                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   10020                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   10021                     }
   10022                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
   10023                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
   10024                             nFilledLen %u nTimeStamp %lld",
   10025                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
   10026                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
   10027                             h264_scratch.nTimeStamp);
   10028                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   10029                         return OMX_ErrorBadParameter;
   10030                     }
   10031                     pdest_frame = NULL;
   10032                     if (m_input_free_q.m_size) {
   10033                         m_input_free_q.pop_entry(&address, &p2, &id);
   10034                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   10035                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
   10036                         pdest_frame->nFilledLen = 0;
   10037                         pdest_frame->nFlags = 0;
   10038                         pdest_frame->nTimeStamp = LLONG_MAX;
   10039                     }
   10040                 }
   10041             }
   10042         }
   10043     } else {
   10044         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
   10045                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
   10046                 nFilledLen %u nTimeStamp %lld",
   10047                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
   10048                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
   10049                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
   10050 
   10051         if (h264_scratch.nAllocLen ==
   10052                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   10053             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   10054             return OMX_ErrorStreamCorrupt;
   10055         }
   10056     }
   10057 
   10058     if (!psource_frame->nFilledLen) {
   10059         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
   10060         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   10061             if (pdest_frame) {
   10062                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   10063                 rc = copy_buffer(pdest_frame, &h264_scratch);
   10064                 if ( rc != OMX_ErrorNone ) {
   10065                     return rc;
   10066                 }
   10067                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   10068                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   10069                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
   10070                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   10071                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   10072                     return OMX_ErrorBadParameter;
   10073                 }
   10074                 frame_count++;
   10075                 pdest_frame = NULL;
   10076             } else {
   10077                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   10078                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   10079                 generate_ebd = OMX_FALSE;
   10080             }
   10081         }
   10082     }
   10083 
   10084     if (generate_ebd && !psource_frame->nFilledLen) {
   10085         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
   10086         psource_frame = NULL;
   10087         if (m_input_pending_q.m_size) {
   10088             m_input_pending_q.pop_entry(&address, &p2, &id);
   10089             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   10090             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
   10091                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
   10092         }
   10093     }
   10094     return OMX_ErrorNone;
   10095 }
   10096 
   10097 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp)
   10098 {
   10099     OMX_U8 *buf, *pdest;
   10100     OMX_U32 partial_frame = 1;
   10101     OMX_U32 buf_len, dest_len;
   10102 
   10103     if (first_frame == 0) {
   10104         first_frame = 1;
   10105         DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
   10106         if (!m_vendor_config.pData) {
   10107             DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
   10108             buf = psource_frame->pBuffer;
   10109             buf_len = psource_frame->nFilledLen;
   10110 
   10111             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   10112                     VC1_SP_MP_START_CODE) {
   10113                 m_vc1_profile = VC1_SP_MP_RCV;
   10114             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   10115                 m_vc1_profile = VC1_AP;
   10116             } else {
   10117                 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
   10118                 return OMX_ErrorStreamCorrupt;
   10119             }
   10120         } else {
   10121             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   10122                 pdest_frame->nOffset;
   10123             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   10124                     pdest_frame->nOffset);
   10125 
   10126             if (dest_len < m_vendor_config.nDataSize) {
   10127                 DEBUG_PRINT_ERROR("Destination buffer full");
   10128                 return OMX_ErrorBadParameter;
   10129             } else {
   10130                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   10131                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   10132             }
   10133         }
   10134     }
   10135 
   10136     switch (m_vc1_profile) {
   10137         case VC1_AP:
   10138             DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
   10139             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   10140                 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
   10141                 return OMX_ErrorBadParameter;
   10142             }
   10143             break;
   10144 
   10145         case VC1_SP_MP_RCV:
   10146         default:
   10147             DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
   10148             return OMX_ErrorBadParameter;
   10149     }
   10150     return OMX_ErrorNone;
   10151 }
   10152 
   10153 #ifndef USE_ION
   10154 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   10155         OMX_U32 alignment)
   10156 {
   10157     struct pmem_allocation allocation;
   10158     allocation.size = buffer_size;
   10159     allocation.align = clip2(alignment);
   10160     if (allocation.align < 4096) {
   10161         allocation.align = 4096;
   10162     }
   10163     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   10164         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
   10165                 allocation.align, allocation.size);
   10166         return false;
   10167     }
   10168     return true;
   10169 }
   10170 #endif
   10171 #ifdef USE_ION
   10172 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   10173         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   10174         struct ion_fd_data *fd_data, int flag)
   10175 {
   10176     int fd = -EINVAL;
   10177     int rc = -EINVAL;
   10178     int ion_dev_flag;
   10179     struct vdec_ion ion_buf_info;
   10180     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   10181         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
   10182         return -EINVAL;
   10183     }
   10184     ion_dev_flag = O_RDONLY;
   10185     fd = open (MEM_DEVICE, ion_dev_flag);
   10186     if (fd < 0) {
   10187         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
   10188         return fd;
   10189     }
   10190 
   10191     alloc_data->flags = flag;
   10192     alloc_data->len = buffer_size;
   10193     alloc_data->align = clip2(alignment);
   10194     if (alloc_data->align < 4096) {
   10195         alloc_data->align = 4096;
   10196     }
   10197 
   10198     alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   10199     if (secure_mode && (alloc_data->flags & ION_SECURE)) {
   10200         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   10201     }
   10202 
   10203     /* Use secure display cma heap for obvious reasons. */
   10204     if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
   10205         alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
   10206     }
   10207 
   10208     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   10209     if (rc || !alloc_data->handle) {
   10210         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
   10211         alloc_data->handle = 0;
   10212         close(fd);
   10213         fd = -ENOMEM;
   10214         return fd;
   10215     }
   10216     fd_data->handle = alloc_data->handle;
   10217     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   10218     if (rc) {
   10219         DEBUG_PRINT_ERROR("ION MAP failed ");
   10220         ion_buf_info.ion_alloc_data = *alloc_data;
   10221         ion_buf_info.ion_device_fd = fd;
   10222         ion_buf_info.fd_ion_data = *fd_data;
   10223         free_ion_memory(&ion_buf_info);
   10224         fd_data->fd =-1;
   10225         fd = -ENOMEM;
   10226     }
   10227 
   10228     return fd;
   10229 }
   10230 
   10231 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   10232 {
   10233 
   10234     if (!buf_ion_info) {
   10235         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
   10236         return;
   10237     }
   10238     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   10239                 &buf_ion_info->ion_alloc_data.handle)) {
   10240         DEBUG_PRINT_ERROR("ION: free failed" );
   10241     }
   10242     close(buf_ion_info->ion_device_fd);
   10243     buf_ion_info->ion_device_fd = -1;
   10244     buf_ion_info->ion_alloc_data.handle = 0;
   10245     buf_ion_info->fd_ion_data.fd = -1;
   10246 }
   10247 #endif
   10248 void omx_vdec::free_output_buffer_header()
   10249 {
   10250     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
   10251     output_use_buffer = false;
   10252     ouput_egl_buffers = false;
   10253 
   10254     if (m_out_mem_ptr) {
   10255         free (m_out_mem_ptr);
   10256         m_out_mem_ptr = NULL;
   10257     }
   10258 
   10259     if (m_platform_list) {
   10260         free(m_platform_list);
   10261         m_platform_list = NULL;
   10262     }
   10263 
   10264     if (drv_ctx.ptr_respbuffer) {
   10265         free (drv_ctx.ptr_respbuffer);
   10266         drv_ctx.ptr_respbuffer = NULL;
   10267     }
   10268     if (drv_ctx.ptr_outputbuffer) {
   10269         free (drv_ctx.ptr_outputbuffer);
   10270         drv_ctx.ptr_outputbuffer = NULL;
   10271     }
   10272 #ifdef USE_ION
   10273     if (drv_ctx.op_buf_ion_info) {
   10274         DEBUG_PRINT_LOW("Free o/p ion context");
   10275         free(drv_ctx.op_buf_ion_info);
   10276         drv_ctx.op_buf_ion_info = NULL;
   10277     }
   10278 #endif
   10279     free(drv_ctx.op_buf_map_info);
   10280     drv_ctx.op_buf_map_info = NULL;
   10281     buf_ref_remove();
   10282 }
   10283 
   10284 void omx_vdec::free_input_buffer_header()
   10285 {
   10286     input_use_buffer = false;
   10287     if (arbitrary_bytes) {
   10288         if (m_inp_heap_ptr) {
   10289             DEBUG_PRINT_LOW("Free input Heap Pointer");
   10290             free (m_inp_heap_ptr);
   10291             m_inp_heap_ptr = NULL;
   10292         }
   10293 
   10294         if (m_phdr_pmem_ptr) {
   10295             DEBUG_PRINT_LOW("Free input pmem header Pointer");
   10296             free (m_phdr_pmem_ptr);
   10297             m_phdr_pmem_ptr = NULL;
   10298         }
   10299     }
   10300     if (m_inp_mem_ptr) {
   10301         DEBUG_PRINT_LOW("Free input pmem Pointer area");
   10302         free (m_inp_mem_ptr);
   10303         m_inp_mem_ptr = NULL;
   10304     }
   10305     /* We just freed all the buffer headers, every thing in m_input_free_q,
   10306      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
   10307     while (m_input_free_q.m_size) {
   10308         unsigned long address, p2, id;
   10309         m_input_free_q.pop_entry(&address, &p2, &id);
   10310     }
   10311     while (m_input_pending_q.m_size) {
   10312         unsigned long address, p2, id;
   10313         m_input_pending_q.pop_entry(&address, &p2, &id);
   10314     }
   10315     pdest_frame = NULL;
   10316     psource_frame = NULL;
   10317     if (drv_ctx.ptr_inputbuffer) {
   10318         DEBUG_PRINT_LOW("Free Driver Context pointer");
   10319         free (drv_ctx.ptr_inputbuffer);
   10320         drv_ctx.ptr_inputbuffer = NULL;
   10321     }
   10322 #ifdef USE_ION
   10323     if (drv_ctx.ip_buf_ion_info) {
   10324         DEBUG_PRINT_LOW("Free ion context");
   10325         free(drv_ctx.ip_buf_ion_info);
   10326         drv_ctx.ip_buf_ion_info = NULL;
   10327     }
   10328 #endif
   10329 }
   10330 
   10331 void omx_vdec::free_output_extradata_buffer_header() {
   10332     client_extradata = false;
   10333     if (m_client_output_extradata_mem_ptr) {
   10334         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
   10335         free(m_client_output_extradata_mem_ptr);
   10336         m_client_output_extradata_mem_ptr = NULL;
   10337     }
   10338 }
   10339 
   10340 int omx_vdec::stream_off(OMX_U32 port)
   10341 {
   10342     enum v4l2_buf_type btype;
   10343     int rc = 0;
   10344     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   10345 
   10346     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   10347         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10348         v4l2_port = OUTPUT_PORT;
   10349     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   10350         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10351         v4l2_port = CAPTURE_PORT;
   10352     } else if (port == OMX_ALL) {
   10353         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   10354         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   10355 
   10356         if (!rc_input)
   10357             return rc_input;
   10358         else
   10359             return rc_output;
   10360     }
   10361 
   10362     if (!streaming[v4l2_port]) {
   10363         // already streamed off, warn and move on
   10364         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   10365                 " which is already streamed off", v4l2_port);
   10366         return 0;
   10367     }
   10368 
   10369     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   10370 
   10371     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   10372     if (rc) {
   10373         /*TODO: How to handle this case */
   10374         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
   10375     } else {
   10376         streaming[v4l2_port] = false;
   10377     }
   10378 
   10379     return rc;
   10380 }
   10381 
   10382 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   10383 {
   10384     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10385     struct v4l2_requestbuffers bufreq;
   10386     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
   10387     unsigned int final_extra_data_size = 0;
   10388     struct v4l2_format fmt;
   10389     int ret = 0;
   10390     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   10391             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10392     bufreq.memory = V4L2_MEMORY_USERPTR;
   10393     bufreq.count = 1;
   10394     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10395         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10396         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10397         fmt.fmt.pix_mp.pixelformat = output_capability;
   10398     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10399         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10400         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10401         fmt.fmt.pix_mp.pixelformat = capture_capability;
   10402     } else {
   10403         eRet = OMX_ErrorBadParameter;
   10404     }
   10405     if (eRet==OMX_ErrorNone) {
   10406         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10407     }
   10408     if (ret) {
   10409         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   10410         /*TODO: How to handle this case */
   10411         eRet = OMX_ErrorInsufficientResources;
   10412         return eRet;
   10413     } else {
   10414         bool is_res_1080p_or_below = (drv_ctx.video_resolution.frame_width <= 1920 &&
   10415                                      drv_ctx.video_resolution.frame_height <= 1088) ||
   10416                                      (drv_ctx.video_resolution.frame_height <= 1088 &&
   10417                                       drv_ctx.video_resolution.frame_width <= 1920);
   10418 
   10419         int fps = drv_ctx.frame_rate.fps_numerator / (float)drv_ctx.frame_rate.fps_denominator;
   10420         bool fps_above_180 =  (fps >= 180 || operating_frame_rate >= 180) ? true : false;
   10421         bool increase_output = (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) && (bufreq.count >= 16);
   10422 
   10423         if (increase_output && fps_above_180 &&
   10424             output_capability == V4L2_PIX_FMT_H264 &&
   10425             is_res_1080p_or_below) {
   10426             m_need_turbo |= TURBO_MODE_HIGH_FPS;
   10427             DEBUG_PRINT_LOW("High fps - fps = %d operating_rate = %d", fps, operating_frame_rate);
   10428             DEBUG_PRINT_LOW("getbufreq[output]: Increase buffer count (%d) to (%d) to support high fps",
   10429                             bufreq.count, bufreq.count + 10);
   10430             bufreq.count += 10;
   10431             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10432             if (ret) {
   10433                 DEBUG_PRINT_ERROR("(Failed to set updated buffer count to driver");
   10434                 eRet = OMX_ErrorInsufficientResources;
   10435                 return eRet;
   10436             }
   10437             DEBUG_PRINT_LOW("new buf count = %d set to driver", bufreq.count);
   10438             request_perf_level(VIDC_TURBO);
   10439         }
   10440 
   10441         buffer_prop->actualcount = bufreq.count;
   10442         buffer_prop->mincount = bufreq.count;
   10443         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
   10444     }
   10445     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   10446             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10447 
   10448     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10449 
   10450     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   10451         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   10452     DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   10453 
   10454     if (ret) {
   10455         /*TODO: How to handle this case */
   10456         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   10457         eRet = OMX_ErrorInsufficientResources;
   10458     } else {
   10459         int extra_idx = 0;
   10460 
   10461         eRet = is_video_session_supported();
   10462         if (eRet)
   10463             return eRet;
   10464 
   10465         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   10466         buf_size = buffer_prop->buffer_size;
   10467         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   10468         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   10469             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   10470         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   10471             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   10472             return OMX_ErrorBadParameter;
   10473         }
   10474 
   10475         default_extra_data_size = VENUS_EXTRADATA_SIZE(
   10476                 drv_ctx.video_resolution.frame_height,
   10477                 drv_ctx.video_resolution.frame_width);
   10478         final_extra_data_size = extra_data_size > default_extra_data_size ?
   10479             extra_data_size : default_extra_data_size;
   10480 
   10481         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
   10482             (~(buffer_prop->alignment - 1));
   10483 
   10484         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
   10485         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   10486         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
   10487         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   10488         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
   10489                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
   10490         if (extra_data_size)
   10491             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
   10492                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
   10493 
   10494         if (in_reconfig) // BufReq will be set to driver when port is disabled
   10495             buffer_prop->buffer_size = buf_size;
   10496         else if (buf_size != buffer_prop->buffer_size) {
   10497             buffer_prop->buffer_size = buf_size;
   10498             eRet = set_buffer_req(buffer_prop);
   10499         }
   10500     }
   10501     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
   10502             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10503     return eRet;
   10504 }
   10505 
   10506 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   10507 {
   10508     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10509     unsigned buf_size = 0;
   10510     struct v4l2_format fmt, c_fmt;
   10511     struct v4l2_requestbuffers bufreq;
   10512     int ret = 0;
   10513     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
   10514             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10515     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   10516     if (buf_size != buffer_prop->buffer_size) {
   10517         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
   10518                 (unsigned int)buffer_prop->buffer_size, buf_size);
   10519         eRet = OMX_ErrorBadParameter;
   10520     } else {
   10521         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   10522         memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
   10523         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   10524         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   10525         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   10526 
   10527         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10528             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10529             fmt.fmt.pix_mp.pixelformat = output_capability;
   10530             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10531         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10532             c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10533             c_fmt.fmt.pix_mp.pixelformat = capture_capability;
   10534             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
   10535             c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   10536             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
   10537         } else {
   10538             eRet = OMX_ErrorBadParameter;
   10539         }
   10540 
   10541         if (ret) {
   10542             /*TODO: How to handle this case */
   10543             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   10544             eRet = OMX_ErrorInsufficientResources;
   10545         }
   10546 
   10547         bufreq.memory = V4L2_MEMORY_USERPTR;
   10548         bufreq.count = buffer_prop->actualcount;
   10549         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10550             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10551         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10552             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10553         } else {
   10554             eRet = OMX_ErrorBadParameter;
   10555         }
   10556 
   10557         if (eRet==OMX_ErrorNone) {
   10558             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10559         }
   10560 
   10561         if (ret) {
   10562             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   10563             /*TODO: How to handle this case */
   10564             eRet = OMX_ErrorInsufficientResources;
   10565         } else if (bufreq.count < buffer_prop->actualcount) {
   10566             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   10567                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   10568                     buffer_prop->actualcount, bufreq.count);
   10569             eRet = OMX_ErrorInsufficientResources;
   10570         } else {
   10571             if (!client_buffers.update_buffer_req()) {
   10572                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   10573                 eRet = OMX_ErrorInsufficientResources;
   10574             }
   10575         }
   10576     }
   10577     return eRet;
   10578 }
   10579 
   10580 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   10581 {
   10582     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10583     return eRet;
   10584 }
   10585 
   10586 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   10587 {
   10588     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10589     struct v4l2_format fmt;
   10590     if (!portDefn) {
   10591         return OMX_ErrorBadParameter;
   10592     }
   10593     DEBUG_PRINT_LOW("omx_vdec::update_portdef");
   10594     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   10595     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   10596     portDefn->eDomain    = OMX_PortDomainVideo;
   10597     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   10598     if (0 == portDefn->nPortIndex) {
   10599         portDefn->eDir =  OMX_DirInput;
   10600         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   10601         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   10602         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   10603         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   10604         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   10605         //for input port, always report the fps value set by client,
   10606         //to distinguish whether client got valid fps from parser.
   10607         portDefn->format.video.xFramerate = m_fps_received;
   10608         portDefn->bEnabled   = m_inp_bEnabled;
   10609         portDefn->bPopulated = m_inp_bPopulated;
   10610 
   10611         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10612         fmt.fmt.pix_mp.pixelformat = output_capability;
   10613         ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10614     } else if (1 == portDefn->nPortIndex) {
   10615         unsigned int buf_size = 0;
   10616         int ret = 0;
   10617        if (in_reconfig && !is_down_scalar_enabled) {
   10618            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10619            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10620            fmt.fmt.pix_mp.pixelformat = capture_capability;
   10621            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10622            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10623        }
   10624 
   10625        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10626        fmt.fmt.pix_mp.pixelformat = capture_capability;
   10627        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10628        if (ret) {
   10629            DEBUG_PRINT_ERROR("Get Resolution failed");
   10630            return OMX_ErrorHardware;
   10631        }
   10632        drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   10633        if (!client_buffers.update_buffer_req()) {
   10634            DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
   10635            return OMX_ErrorHardware;
   10636        }
   10637 
   10638         if (!client_buffers.get_buffer_req(buf_size)) {
   10639             DEBUG_PRINT_ERROR("update buffer requirements");
   10640             return OMX_ErrorHardware;
   10641         }
   10642         portDefn->nBufferSize = buf_size;
   10643         portDefn->eDir =  OMX_DirOutput;
   10644         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   10645         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   10646         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   10647         if (drv_ctx.frame_rate.fps_denominator > 0)
   10648             portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
   10649                 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
   10650         else {
   10651             DEBUG_PRINT_ERROR("Error: Divide by zero");
   10652             return OMX_ErrorBadParameter;
   10653         }
   10654         portDefn->bEnabled   = m_out_bEnabled;
   10655         portDefn->bPopulated = m_out_bPopulated;
   10656         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   10657             DEBUG_PRINT_ERROR("Error in getting color format");
   10658             return OMX_ErrorHardware;
   10659         }
   10660         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10661         fmt.fmt.pix_mp.pixelformat = capture_capability;
   10662     } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
   10663         portDefn->nBufferSize = m_client_out_extradata_info.getSize();
   10664         portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
   10665         portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
   10666         portDefn->eDir =  OMX_DirOutput;
   10667     } else {
   10668         portDefn->eDir = OMX_DirMax;
   10669         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   10670                 (int)portDefn->nPortIndex);
   10671         eRet = OMX_ErrorBadPortIndex;
   10672     }
   10673     update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
   10674         fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   10675 
   10676         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   10677         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   10678         portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   10679         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   10680 
   10681     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
   10682        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
   10683            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
   10684            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
   10685     }
   10686     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
   10687             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
   10688             (unsigned int)portDefn->nPortIndex,
   10689             (unsigned int)portDefn->format.video.nFrameWidth,
   10690             (unsigned int)portDefn->format.video.nFrameHeight,
   10691             (int)portDefn->format.video.nStride,
   10692             (unsigned int)portDefn->format.video.nSliceHeight,
   10693             (unsigned int)portDefn->format.video.eColorFormat,
   10694             (unsigned int)portDefn->nBufferSize,
   10695             (unsigned int)portDefn->nBufferCountActual);
   10696 
   10697     return eRet;
   10698 }
   10699 
   10700 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   10701 {
   10702     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10703     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   10704     unsigned i = 0;
   10705 
   10706     if (!m_out_mem_ptr) {
   10707         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
   10708         int nBufHdrSize        = 0;
   10709         int nPlatformEntrySize = 0;
   10710         int nPlatformListSize  = 0;
   10711         int nPMEMInfoSize = 0;
   10712         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   10713         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   10714         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   10715 
   10716         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
   10717                 drv_ctx.op_buf.actualcount);
   10718         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   10719             sizeof(OMX_BUFFERHEADERTYPE);
   10720 
   10721         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   10722             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   10723         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   10724             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   10725         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   10726             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   10727 
   10728         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   10729                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   10730                 nPMEMInfoSize,
   10731                 nPlatformListSize);
   10732         DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
   10733                 m_out_bm_count);
   10734         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   10735         // Alloc mem for platform specific info
   10736         char *pPtr=NULL;
   10737         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   10738                 nPMEMInfoSize,1);
   10739         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   10740                        calloc (sizeof(struct vdec_bufferpayload),
   10741                                drv_ctx.op_buf.actualcount);
   10742         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   10743                      calloc (sizeof (struct vdec_output_frameinfo),
   10744                              drv_ctx.op_buf.actualcount);
   10745         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   10746             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
   10747             return OMX_ErrorInsufficientResources;
   10748         }
   10749 
   10750 #ifdef USE_ION
   10751         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   10752                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   10753         if (!drv_ctx.op_buf_ion_info) {
   10754             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   10755             return OMX_ErrorInsufficientResources;
   10756         }
   10757 #endif
   10758         if (dynamic_buf_mode) {
   10759             out_dynamic_list = (struct dynamic_buf_list *) \
   10760                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   10761             if (out_dynamic_list) {
   10762                for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++)
   10763                   out_dynamic_list[i].dup_fd = -1;
   10764             }
   10765         }
   10766 
   10767         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   10768                 && drv_ctx.ptr_respbuffer) {
   10769             bufHdr          =  m_out_mem_ptr;
   10770             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   10771             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   10772                 (((char *) m_platform_list)  + nPlatformListSize);
   10773             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   10774                 (((char *) m_platform_entry) + nPlatformEntrySize);
   10775             pPlatformList   = m_platform_list;
   10776             pPlatformEntry  = m_platform_entry;
   10777             pPMEMInfo       = m_pmem_info;
   10778 
   10779             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   10780 
   10781             // Settting the entire storage nicely
   10782             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
   10783                     m_out_mem_ptr,pPlatformEntry);
   10784             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   10785             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   10786                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   10787                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   10788                 // Set the values when we determine the right HxW param
   10789                 bufHdr->nAllocLen          = 0;
   10790                 bufHdr->nFilledLen         = 0;
   10791                 bufHdr->pAppPrivate        = NULL;
   10792                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   10793                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   10794                 pPlatformEntry->entry      = pPMEMInfo;
   10795                 // Initialize the Platform List
   10796                 pPlatformList->nEntries    = 1;
   10797                 pPlatformList->entryList   = pPlatformEntry;
   10798                 // Keep pBuffer NULL till vdec is opened
   10799                 bufHdr->pBuffer            = NULL;
   10800                 pPMEMInfo->offset          =  0;
   10801                 pPMEMInfo->pmem_fd = -1;
   10802                 bufHdr->pPlatformPrivate = pPlatformList;
   10803                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   10804 #ifdef USE_ION
   10805                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   10806 #endif
   10807                 /*Create a mapping between buffers*/
   10808                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   10809                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   10810                                     &drv_ctx.ptr_outputbuffer[i];
   10811                 // Move the buffer and buffer header pointers
   10812                 bufHdr++;
   10813                 pPMEMInfo++;
   10814                 pPlatformEntry++;
   10815                 pPlatformList++;
   10816             }
   10817         } else {
   10818             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   10819                     m_out_mem_ptr, pPtr);
   10820             if (m_out_mem_ptr) {
   10821                 free(m_out_mem_ptr);
   10822                 m_out_mem_ptr = NULL;
   10823             }
   10824             if (pPtr) {
   10825                 free(pPtr);
   10826                 pPtr = NULL;
   10827             }
   10828             if (drv_ctx.ptr_outputbuffer) {
   10829                 free(drv_ctx.ptr_outputbuffer);
   10830                 drv_ctx.ptr_outputbuffer = NULL;
   10831             }
   10832             if (drv_ctx.ptr_respbuffer) {
   10833                 free(drv_ctx.ptr_respbuffer);
   10834                 drv_ctx.ptr_respbuffer = NULL;
   10835             }
   10836 #ifdef USE_ION
   10837             if (drv_ctx.op_buf_ion_info) {
   10838                 DEBUG_PRINT_LOW("Free o/p ion context");
   10839                 free(drv_ctx.op_buf_ion_info);
   10840                 drv_ctx.op_buf_ion_info = NULL;
   10841             }
   10842 #endif
   10843             free(drv_ctx.op_buf_map_info);
   10844             drv_ctx.op_buf_map_info = NULL;
   10845             eRet =  OMX_ErrorInsufficientResources;
   10846         }
   10847     } else {
   10848         eRet =  OMX_ErrorInsufficientResources;
   10849     }
   10850     return eRet;
   10851 }
   10852 
   10853 void omx_vdec::complete_pending_buffer_done_cbs()
   10854 {
   10855     unsigned long p1, p2, ident;
   10856     omx_cmd_queue tmp_q, pending_bd_q;
   10857     pthread_mutex_lock(&m_lock);
   10858     // pop all pending GENERATE FDB from ftb queue
   10859     while (m_ftb_q.m_size) {
   10860         m_ftb_q.pop_entry(&p1,&p2,&ident);
   10861         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   10862             pending_bd_q.insert_entry(p1,p2,ident);
   10863         } else {
   10864             tmp_q.insert_entry(p1,p2,ident);
   10865         }
   10866     }
   10867     //return all non GENERATE FDB to ftb queue
   10868     while (tmp_q.m_size) {
   10869         tmp_q.pop_entry(&p1,&p2,&ident);
   10870         m_ftb_q.insert_entry(p1,p2,ident);
   10871     }
   10872     // pop all pending GENERATE EDB from etb queue
   10873     while (m_etb_q.m_size) {
   10874         m_etb_q.pop_entry(&p1,&p2,&ident);
   10875         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   10876             pending_bd_q.insert_entry(p1,p2,ident);
   10877         } else {
   10878             tmp_q.insert_entry(p1,p2,ident);
   10879         }
   10880     }
   10881     //return all non GENERATE FDB to etb queue
   10882     while (tmp_q.m_size) {
   10883         tmp_q.pop_entry(&p1,&p2,&ident);
   10884         m_etb_q.insert_entry(p1,p2,ident);
   10885     }
   10886     pthread_mutex_unlock(&m_lock);
   10887     // process all pending buffer dones
   10888     while (pending_bd_q.m_size) {
   10889         pending_bd_q.pop_entry(&p1,&p2,&ident);
   10890         switch (ident) {
   10891             case OMX_COMPONENT_GENERATE_EBD:
   10892                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   10893                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   10894                     omx_report_error ();
   10895                 }
   10896                 break;
   10897 
   10898             case OMX_COMPONENT_GENERATE_FBD:
   10899                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   10900                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   10901                     omx_report_error ();
   10902                 }
   10903                 break;
   10904         }
   10905     }
   10906 }
   10907 
   10908 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   10909 {
   10910     OMX_U32 new_frame_interval = 0;
   10911     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   10912             && llabs(act_timestamp - prev_ts) > 2000) {
   10913         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
   10914             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
   10915         if (new_frame_interval != frm_int || frm_int == 0) {
   10916             frm_int = new_frame_interval;
   10917             if (frm_int) {
   10918                 drv_ctx.frame_rate.fps_numerator = 1e6;
   10919                 drv_ctx.frame_rate.fps_denominator = frm_int;
   10920                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
   10921                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   10922                         (float)drv_ctx.frame_rate.fps_denominator);
   10923                 m_perf_control.request_cores(frm_int);
   10924                 /* We need to report the difference between this FBD and the previous FBD
   10925                  * back to the driver for clock scaling purposes. */
   10926                 struct v4l2_outputparm oparm;
   10927                 /*XXX: we're providing timing info as seconds per frame rather than frames
   10928                  * per second.*/
   10929                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   10930                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   10931 
   10932                 struct v4l2_streamparm sparm;
   10933                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10934                 sparm.parm.output = oparm;
   10935                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   10936                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   10937                             performance might be affected");
   10938                 }
   10939 
   10940             }
   10941         }
   10942     }
   10943     prev_ts = act_timestamp;
   10944 }
   10945 
   10946 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   10947 {
   10948     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   10949         prev_ts = act_timestamp;
   10950         prev_ts_actual = act_timestamp;
   10951         rst_prev_ts = false;
   10952     } else if (VALID_TS(prev_ts)) {
   10953         bool codec_cond = (drv_ctx.timestamp_adjust)?
   10954             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
   10955             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
   10956              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
   10957         if (frm_int > 0 && codec_cond) {
   10958             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   10959             act_timestamp = prev_ts + frm_int;
   10960             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   10961             prev_ts = act_timestamp;
   10962         } else {
   10963             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
   10964                 // ensure that timestamps can never step backwards when in display order
   10965                 act_timestamp = prev_ts;
   10966             }
   10967             set_frame_rate(act_timestamp);
   10968         }
   10969     } else if (frm_int > 0)          // In this case the frame rate was set along
   10970     {                               // with the port definition, start ts with 0
   10971         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   10972         rst_prev_ts = true;
   10973     }
   10974 }
   10975 
   10976 OMX_BUFFERHEADERTYPE* omx_vdec::get_omx_output_buffer_header(int index)
   10977 {
   10978     return m_out_mem_ptr + index;
   10979 }
   10980 
   10981 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
   10982     OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects)
   10983 {
   10984     switch (primaries) {
   10985         case MSM_VIDC_BT709_5:
   10986             *color_space = ITU_R_709;
   10987             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
   10988             break;
   10989         case MSM_VIDC_BT470_6_M:
   10990             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
   10991             break;
   10992         case MSM_VIDC_BT601_6_625:
   10993             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10994             break;
   10995         case MSM_VIDC_BT601_6_525:
   10996             *color_space = range ? ITU_R_601_FR : ITU_R_601;
   10997             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   10998             break;
   10999         case MSM_VIDC_GENERIC_FILM:
   11000             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
   11001             break;
   11002         case MSM_VIDC_BT2020:
   11003             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   11004             break;
   11005         case MSM_VIDC_UNSPECIFIED:
   11006             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
   11007         default:
   11008             //aspects->mPrimaries = ColorAspects::PrimariesOther;
   11009             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   11010             break;
   11011     }
   11012 
   11013     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
   11014 
   11015     switch (transfer) {
   11016         case MSM_VIDC_TRANSFER_BT709_5:
   11017         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
   11018             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11019             break;
   11020         case MSM_VIDC_TRANSFER_BT_470_6_M:
   11021             aspects->mTransfer = ColorAspects::TransferGamma22;
   11022             break;
   11023         case MSM_VIDC_TRANSFER_BT_470_6_BG:
   11024             aspects->mTransfer = ColorAspects::TransferGamma28;
   11025             break;
   11026         case MSM_VIDC_TRANSFER_SMPTE_240M:
   11027             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   11028             break;
   11029         case MSM_VIDC_TRANSFER_LINEAR:
   11030             aspects->mTransfer = ColorAspects::TransferLinear;
   11031             break;
   11032         case MSM_VIDC_TRANSFER_IEC_61966:
   11033             aspects->mTransfer = ColorAspects::TransferXvYCC;
   11034             break;
   11035         case MSM_VIDC_TRANSFER_BT_1361:
   11036             aspects->mTransfer = ColorAspects::TransferBT1361;
   11037             break;
   11038         case MSM_VIDC_TRANSFER_SRGB:
   11039             aspects->mTransfer = ColorAspects::TransferSRGB;
   11040             break;
   11041         case MSM_VIDC_TRANSFER_SMPTE_ST2084:
   11042             aspects->mTransfer = ColorAspects::TransferST2084;
   11043             break;
   11044         case MSM_VIDC_TRANSFER_HLG:
   11045             aspects->mTransfer = ColorAspects::TransferHLG;
   11046             break;
   11047         default:
   11048             //aspects->mTransfer = ColorAspects::TransferOther;
   11049             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
   11050             break;
   11051     }
   11052 
   11053     switch (matrix) {
   11054         case MSM_VIDC_MATRIX_BT_709_5:
   11055             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11056             break;
   11057         case MSM_VIDC_MATRIX_FCC_47:
   11058             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
   11059             break;
   11060         case MSM_VIDC_MATRIX_601_6_625:
   11061         case MSM_VIDC_MATRIX_601_6_525:
   11062             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   11063             break;
   11064         case MSM_VIDC_MATRIX_SMPTE_240M:
   11065             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
   11066             break;
   11067         case MSM_VIDC_MATRIX_BT_2020:
   11068             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   11069             break;
   11070         case MSM_VIDC_MATRIX_BT_2020_CONST:
   11071             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
   11072             break;
   11073         default:
   11074             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   11075             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   11076             break;
   11077     }
   11078 }
   11079 
   11080 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) {
   11081         DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)",
   11082                 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange),
   11083                 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs));
   11084 }
   11085 
   11086 void omx_vdec::prepare_color_aspects_metadata(OMX_U32 primaries, OMX_U32 range,
   11087                                               OMX_U32 transfer, OMX_U32 matrix,
   11088                                               ColorMetaData *color_mdata)
   11089 {
   11090 
   11091     /* ColorAspects in qdMetaData */
   11092     color_mdata->colorPrimaries = (enum ColorPrimaries) primaries;
   11093     color_mdata->range = (enum ColorRange)range;
   11094     color_mdata->transfer = (enum GammaTransfer)transfer;
   11095     color_mdata->matrixCoefficients = (enum MatrixCoEfficients)matrix;
   11096 }
   11097 
   11098 bool omx_vdec::handle_color_space_info(void *data,
   11099                                        ColorSpace_t *color_space,
   11100                                        ColorMetaData *color_mdata,
   11101                                        bool& set_color_aspects_only)
   11102 {
   11103     ColorAspects tempAspects;
   11104     memset(&tempAspects, 0x0, sizeof(ColorAspects));
   11105     ColorAspects *aspects = &tempAspects;
   11106 
   11107     /* Set default ColorAspects */
   11108     prepare_color_aspects_metadata(ColorPrimaries_BT601_6_625, Range_Full,
   11109                                            Transfer_SMPTE_170M, MatrixCoEff_BT601_6_625,
   11110                                            color_mdata);
   11111 
   11112     switch(output_capability) {
   11113         case V4L2_PIX_FMT_MPEG2:
   11114             {
   11115                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   11116                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
   11117 
   11118                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
   11119                  * understand this code */
   11120 
   11121                 if (seqdisp_payload && seqdisp_payload->color_descp) {
   11122 
   11123                     convert_color_space_info(seqdisp_payload->color_primaries, 1,
   11124                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   11125                             color_space,aspects);
   11126                     m_disp_hor_size = seqdisp_payload->disp_width;
   11127                     m_disp_vert_size = seqdisp_payload->disp_height;
   11128                     set_color_aspects_only = true;
   11129                     prepare_color_aspects_metadata(seqdisp_payload->color_primaries, 1,
   11130                                                     seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   11131                                                     color_mdata);
   11132                 }
   11133             }
   11134             break;
   11135         case V4L2_PIX_FMT_H264:
   11136         case V4L2_PIX_FMT_HEVC:
   11137             {
   11138                 struct msm_vidc_vui_display_info_payload *display_info_payload;
   11139                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
   11140 
   11141                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
   11142 
   11143                 if (display_info_payload->video_signal_present_flag &&
   11144                         display_info_payload->color_description_present_flag) {
   11145                     convert_color_space_info(display_info_payload->color_primaries,
   11146                             display_info_payload->video_full_range_flag,
   11147                             display_info_payload->transfer_characteristics,
   11148                             display_info_payload->matrix_coefficients,
   11149                             color_space,aspects);
   11150                     set_color_aspects_only = true;
   11151                     prepare_color_aspects_metadata(display_info_payload->color_primaries,
   11152                                                    display_info_payload->video_full_range_flag,
   11153                                                    display_info_payload->transfer_characteristics,
   11154                                                    display_info_payload->matrix_coefficients,
   11155                                                    color_mdata);
   11156                 }
   11157             }
   11158             break;
   11159         case V4L2_PIX_FMT_VC1_ANNEX_G:
   11160         case V4L2_PIX_FMT_VC1_ANNEX_L:
   11161             {
   11162                 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload;
   11163                 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data;
   11164 
   11165                 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23
   11166                  * SMPTE 421M to understand this code */
   11167 
   11168                 if (m_enable_android_native_buffers &&
   11169                         vc1_seq_disp_payload->color_primaries) {
   11170 
   11171                     convert_color_space_info(vc1_seq_disp_payload->color_primaries,
   11172                             1,
   11173                             vc1_seq_disp_payload->transfer_char,
   11174                             vc1_seq_disp_payload->matrix_coeffs,
   11175                             color_space,aspects);
   11176                     set_color_aspects_only = true;
   11177                     prepare_color_aspects_metadata(vc1_seq_disp_payload->color_primaries,
   11178                                                    1,
   11179                                                    vc1_seq_disp_payload->transfer_char,
   11180                                                    vc1_seq_disp_payload->matrix_coeffs,
   11181                                                    color_mdata);
   11182                 }
   11183             }
   11184             break;
   11185         case V4L2_PIX_FMT_VP8:
   11186             {
   11187                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   11188                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   11189                 set_color_aspects_only = false;
   11190                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
   11191                  * to understand this code */
   11192 
   11193                 if (vpx_color_space_payload->color_space == 0) {
   11194                     *color_space = ITU_R_601;
   11195                     aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   11196                     aspects->mRange = ColorAspects::RangeLimited;
   11197                 } else {
   11198                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
   11199                     break;
   11200                 }
   11201             }
   11202             break;
   11203         case V4L2_PIX_FMT_VP9:
   11204             {
   11205                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   11206                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   11207                 set_color_aspects_only = false;
   11208                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
   11209                  * to understand this code */
   11210 
   11211                 switch(vpx_color_space_payload->color_space) {
   11212                     case MSM_VIDC_CS_BT_601:
   11213                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   11214                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11215                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   11216                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11217                         break;
   11218                     case MSM_VIDC_CS_BT_709:
   11219                         *color_space = ITU_R_709;
   11220                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11221                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11222                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
   11223                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11224                         break;
   11225                     case MSM_VIDC_CS_SMPTE_170:
   11226                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11227                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11228                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   11229                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11230                         break;
   11231                     case MSM_VIDC_CS_SMPTE_240:
   11232                         aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   11233                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   11234                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   11235                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11236                         break;
   11237                     case MSM_VIDC_CS_BT_2020:
   11238                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   11239                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
   11240                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   11241                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11242                         break;
   11243                     case MSM_VIDC_CS_RESERVED:
   11244                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   11245                         aspects->mTransfer = ColorAspects::TransferOther;
   11246                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   11247                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11248                         break;
   11249                     case MSM_VIDC_CS_RGB:
   11250                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11251                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11252                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   11253                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11254                         break;
   11255                     default:
   11256                         break;
   11257                 }
   11258             }
   11259             break;
   11260         default:
   11261             break;
   11262     }
   11263 
   11264     print_debug_color_aspects(aspects, "Bitstream");
   11265 
   11266     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
   11267             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
   11268             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
   11269             m_internal_color_space.sAspects.mRange != aspects->mRange) {
   11270         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
   11271 
   11272         m_color_mdata.colorPrimaries = color_mdata->colorPrimaries;
   11273         m_color_mdata.range = color_mdata->range;
   11274         m_color_mdata.transfer = color_mdata->transfer;
   11275         m_color_mdata.matrixCoefficients = color_mdata->matrixCoefficients;
   11276 
   11277         DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change");
   11278         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
   11279         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
   11280 
   11281         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   11282                 OMX_QTIIndexConfigDescribeColorAspects,
   11283                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   11284         return true;
   11285     }
   11286     return false;
   11287 }
   11288 
   11289 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
   11290     private_handle_t *private_handle = NULL;
   11291     if (buf_index < drv_ctx.op_buf.actualcount &&
   11292             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   11293             native_buffer[buf_index].privatehandle) {
   11294         private_handle = native_buffer[buf_index].privatehandle;
   11295     }
   11296     if (private_handle) {
   11297         setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
   11298     }
   11299 }
   11300 
   11301 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix)
   11302 {
   11303     if (!hdr_info->mID) {
   11304         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix,
   11305                          hdr_info->sType1.mR.x, hdr_info->sType1.mR.y);
   11306         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix,
   11307                          hdr_info->sType1.mG.x, hdr_info->sType1.mG.y);
   11308         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix,
   11309                          hdr_info->sType1.mB.x, hdr_info->sType1.mB.y);
   11310         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix,
   11311                          hdr_info->sType1.mW.x, hdr_info->sType1.mW.y);
   11312         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix,
   11313                          hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance);
   11314         DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix,
   11315                         hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel);
   11316     }
   11317 
   11318 }
   11319 
   11320 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata)
   11321 {
   11322     DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u",
   11323                     color_mdata->colorPrimaries, color_mdata->range,
   11324                     color_mdata->transfer, color_mdata->matrixCoefficients);
   11325 
   11326     for(uint8_t i = 0; i < 3; i++) {
   11327         for(uint8_t j = 0; j < 2; j++) {
   11328             DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
   11329         }
   11330     }
   11331 
   11332     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d",
   11333                     color_mdata->masteringDisplayInfo.primaries.whitePoint[0],
   11334                     color_mdata->masteringDisplayInfo.primaries.whitePoint[1]);
   11335 
   11336     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d",
   11337                     color_mdata->masteringDisplayInfo.maxDisplayLuminance,
   11338                     color_mdata->masteringDisplayInfo.minDisplayLuminance);
   11339 
   11340     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d",
   11341                     color_mdata->contentLightLevel.maxContentLightLevel,
   11342                     color_mdata->contentLightLevel.minPicAverageLightLevel);
   11343 
   11344 
   11345 }
   11346 
   11347 bool omx_vdec::handle_content_light_level_info(void* data, ContentLightLevel* light_level_mdata)
   11348 {
   11349     struct msm_vidc_content_light_level_sei_payload *light_level_payload =
   11350         (msm_vidc_content_light_level_sei_payload*)(data);
   11351 
   11352     light_level_mdata->lightLevelSEIEnabled = true;
   11353     light_level_mdata->maxContentLightLevel = light_level_payload->nMaxContentLight;
   11354     light_level_mdata->minPicAverageLightLevel = light_level_payload->nMaxPicAverageLight;
   11355 
   11356     if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) ||
   11357         (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) {
   11358         m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight;
   11359         m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight;
   11360         return true;
   11361     }
   11362     return false;
   11363 }
   11364 
   11365 bool omx_vdec::handle_mastering_display_color_info(void* data, MasteringDisplay* mastering_display_mdata)
   11366 {
   11367     struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload =
   11368         (msm_vidc_mastering_display_colour_sei_payload*)(data);
   11369     HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo;
   11370     bool internal_disp_changed_flag = false;
   11371 
   11372     mastering_display_mdata->colorVolumeSEIEnabled = true;
   11373     for (uint8_t i = 0; i < 3; i++) {
   11374         mastering_display_mdata->primaries.rgbPrimaries[i][0] = mastering_display_payload->nDisplayPrimariesX[i];
   11375         mastering_display_mdata->primaries.rgbPrimaries[i][1] = mastering_display_payload->nDisplayPrimariesY[i];
   11376     }
   11377     mastering_display_mdata->primaries.whitePoint[0] = mastering_display_payload->nWhitePointX;
   11378     mastering_display_mdata->primaries.whitePoint[1] = mastering_display_payload->nWhitePointY;
   11379     mastering_display_mdata->maxDisplayLuminance = mastering_display_payload->nMaxDisplayMasteringLuminance;
   11380     mastering_display_mdata->minDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
   11381 
   11382     internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[0]) ||
   11383         (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[0]);
   11384     internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[1]) ||
   11385         (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[1]);
   11386     internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[2]) ||
   11387         (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[2]);
   11388 
   11389     internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) ||
   11390         (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY);
   11391 
   11392     /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension
   11393        requires it in cd/m2, so dividing by 10000 and rounding the value after division
   11394     */
   11395     uint16_t max_display_luminance_cd_m2 =
   11396         static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5);
   11397     internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) ||
   11398         (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance);
   11399 
   11400     if (internal_disp_changed_flag) {
   11401         hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[0];
   11402         hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[0];
   11403         hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[1];
   11404         hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[1];
   11405         hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[2];
   11406         hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[2];
   11407         hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX;
   11408         hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY;
   11409 
   11410         hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2;
   11411         hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
   11412     }
   11413 
   11414     return internal_disp_changed_flag;
   11415 }
   11416 
   11417 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index)
   11418 {
   11419     private_handle_t *private_handle = NULL;
   11420     if (buf_index < drv_ctx.op_buf.actualcount &&
   11421         buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   11422         native_buffer[buf_index].privatehandle) {
   11423         private_handle = native_buffer[buf_index].privatehandle;
   11424     }
   11425     if (private_handle) {
   11426         setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata);
   11427     }
   11428 }
   11429 
   11430 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   11431 {
   11432     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
   11433     OMX_U8 *pBuffer = NULL;
   11434     OMX_U32 num_conceal_MB = 0;
   11435     OMX_TICKS time_stamp = 0;
   11436     OMX_U32 frame_rate = 0;
   11437     unsigned long consumed_len = 0;
   11438     OMX_U32 num_MB_in_frame;
   11439     OMX_U32 recovery_sei_flags = 1;
   11440     int enable = OMX_InterlaceFrameProgressive;
   11441     bool internal_hdr_info_changed_flag = false;
   11442     bool color_event = false;
   11443     ColorMetaData color_mdata;
   11444     memset(&color_mdata, 0x0, sizeof(ColorMetaData));
   11445     bool set_disp_color_aspects_only = false;
   11446     ColorSpace_t color_space = ITU_R_601;
   11447 
   11448     int buf_index = p_buf_hdr - m_out_mem_ptr;
   11449     if (buf_index >= drv_ctx.extradata_info.count) {
   11450         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   11451                 buf_index, drv_ctx.extradata_info.count);
   11452         return;
   11453     }
   11454     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   11455 
   11456     if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) {
   11457         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
   11458         return;
   11459     }
   11460 
   11461     if (!drv_ctx.extradata_info.uaddr) {
   11462         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
   11463         return;
   11464     }
   11465     if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
   11466         DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
   11467         p_extra = NULL;
   11468         return;
   11469     }
   11470     if (!secure_mode) {
   11471         pBuffer = (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len,
   11472                     PROT_READ|PROT_WRITE, MAP_SHARED, drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0);
   11473         if (pBuffer == MAP_FAILED) {
   11474             DEBUG_PRINT_ERROR("handle_extradata output buffer mmap failed - errno: %d", errno);
   11475             return;
   11476         }
   11477         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   11478             ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   11479     } else
   11480         p_extra = m_other_extradata;
   11481 
   11482     AutoUnmap autounmap(pBuffer, drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
   11483     if (m_client_output_extradata_mem_ptr &&
   11484         m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
   11485         p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer);
   11486     }
   11487 
   11488     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   11489 
   11490     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   11491         p_extra = NULL;
   11492         DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   11493         return;
   11494     }
   11495     m_extradata_info.output_crop_updated = OMX_FALSE;
   11496     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   11497     if (data && p_extra) {
   11498         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   11499                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
   11500             if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
   11501                 DEBUG_PRINT_LOW("Invalid extra data size");
   11502                 break;
   11503             }
   11504 
   11505             if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   11506                 p_extra = NULL;
   11507                 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   11508                 return;
   11509             }
   11510 
   11511             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
   11512             switch ((unsigned long)data->eType) {
   11513                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
   11514                     struct msm_vidc_interlace_payload *payload;
   11515                     OMX_U32 interlace_color_format;
   11516                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
   11517                     if (payload) {
   11518                         enable = OMX_InterlaceFrameProgressive;
   11519                         switch (payload->format) {
   11520                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
   11521                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11522                                 break;
   11523                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
   11524                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   11525                                 enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
   11526                                 break;
   11527                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
   11528                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   11529                                 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   11530                                 break;
   11531                             default:
   11532                                 DEBUG_PRINT_LOW("default case - set to progressive");
   11533                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11534                         }
   11535                         switch (payload->color_format) {
   11536                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12:
   11537                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11538                                break;
   11539                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC:
   11540                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11541                                break;
   11542                            default:
   11543                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11544                                DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame");
   11545                         }
   11546                     }
   11547 
   11548                     if (m_enable_android_native_buffers) {
   11549                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d",
   11550                                          payload->format, interlace_color_format ,enable,
   11551                                         (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
   11552 
   11553                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11554                                PP_PARAM_INTERLACED, (void*)&enable);
   11555 
   11556                         if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   11557                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11558                                LINEAR_FORMAT, (void*)&interlace_color_format);
   11559                         } else if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   11560                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11561                                LINEAR_FORMAT, NULL);
   11562                         }
   11563                     }
   11564                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   11565                         append_interlace_extradata(p_extra, payload->format);
   11566                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11567                         if (p_client_extra) {
   11568                             append_interlace_extradata(p_client_extra, payload->format);
   11569                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
   11570                                 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11571                         }
   11572                     }
   11573                     break;
   11574                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
   11575                     struct msm_vidc_framerate_payload *frame_rate_payload;
   11576                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
   11577                     frame_rate = frame_rate_payload->frame_rate;
   11578                     break;
   11579                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
   11580                     struct msm_vidc_ts_payload *time_stamp_payload;
   11581                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
   11582                     time_stamp = time_stamp_payload->timestamp_lo;
   11583                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   11584                     p_buf_hdr->nTimeStamp = time_stamp;
   11585                     break;
   11586                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
   11587                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   11588                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
   11589                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   11590                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   11591                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   11592                     break;
   11593                 case MSM_VIDC_EXTRADATA_INDEX:
   11594                     int *etype;
   11595                     etype  = (int *)(void *)data->data;
   11596                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
   11597                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   11598                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   11599                         if (aspect_ratio_payload) {
   11600                             ((struct vdec_output_frameinfo *)
   11601                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   11602                             ((struct vdec_output_frameinfo *)
   11603                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   11604                         }
   11605                     } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
   11606                         struct msm_vidc_output_crop_payload *output_crop_payload;
   11607                         output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
   11608                         if (output_crop_payload) {
   11609                             m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
   11610                             m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
   11611                             m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
   11612                             m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
   11613                             m_extradata_info.output_width = output_crop_payload->width;
   11614                             m_extradata_info.output_height = output_crop_payload->height;
   11615                             m_extradata_info.output_crop_updated = OMX_TRUE;
   11616                         }
   11617                     }
   11618                     break;
   11619                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
   11620                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   11621                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
   11622                     recovery_sei_flags = recovery_sei_payload->flags;
   11623                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
   11624                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   11625                         DEBUG_PRINT_HIGH("***************************************************");
   11626                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   11627                         DEBUG_PRINT_HIGH("***************************************************");
   11628                     }
   11629                     break;
   11630                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
   11631                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
   11632                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
   11633                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
   11634                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
   11635                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
   11636                         return;
   11637                     }
   11638                     break;
   11639                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
   11640                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
   11641                 case MSM_VIDC_EXTRADATA_VC1_SEQDISP:
   11642                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
   11643                     color_event = handle_color_space_info((void *)data->data, &color_space, &color_mdata, set_disp_color_aspects_only);
   11644                     break;
   11645                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
   11646                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
   11647                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
   11648                     switch (s3d_frame_packing_payload->fpa_type) {
   11649                         case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
   11650                             if (s3d_frame_packing_payload->content_interprtation_type == 1)
   11651                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
   11652                             else if (s3d_frame_packing_payload->content_interprtation_type == 2)
   11653                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
   11654                             else {
   11655                                 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
   11656                                 stereo_output_mode = HAL_NO_3D;
   11657                             }
   11658                             break;
   11659                         case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
   11660                             stereo_output_mode = HAL_3D_TOP_BOTTOM;
   11661                             break;
   11662                         default:
   11663                             DEBUG_PRINT_ERROR("Unsupported framepacking type");
   11664                             stereo_output_mode = HAL_NO_3D;
   11665                     }
   11666                     DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
   11667                         s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
   11668                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
   11669                         append_framepack_extradata(p_extra, s3d_frame_packing_payload);
   11670                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11671                         if (p_client_extra) {
   11672                             append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
   11673                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11674                         }
   11675                     }
   11676                     break;
   11677                 case MSM_VIDC_EXTRADATA_FRAME_QP:
   11678                     struct msm_vidc_frame_qp_payload *qp_payload;
   11679                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
   11680                     if (client_extradata & OMX_QP_EXTRADATA) {
   11681                         append_qp_extradata(p_extra, qp_payload);
   11682                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11683                         if (p_client_extra) {
   11684                             append_qp_extradata(p_client_extra, qp_payload);
   11685                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11686                         }
   11687                     }
   11688                     break;
   11689                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
   11690                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
   11691                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
   11692                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
   11693                         append_bitsinfo_extradata(p_extra, bits_info_payload);
   11694                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11695                         if (p_client_extra) {
   11696                             append_bitsinfo_extradata(p_client_extra, bits_info_payload);
   11697                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11698                         }
   11699                     }
   11700                     break;
   11701                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
   11702                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
   11703                         append_user_extradata(p_extra, data);
   11704                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11705                         if (p_client_extra) {
   11706                             append_user_extradata(p_client_extra, data);
   11707                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11708                         }
   11709                     }
   11710                     break;
   11711                 case MSM_VIDC_EXTRADATA_VQZIP_SEI:
   11712                     struct msm_vidc_vqzip_sei_payload *vqzip_payload;
   11713                     vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data;
   11714                     if (client_extradata & OMX_VQZIPSEI_EXTRADATA) {
   11715                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11716                         append_vqzip_extradata(p_extra, vqzip_payload);
   11717                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11718                         if (p_client_extra) {
   11719                             append_vqzip_extradata(p_client_extra, vqzip_payload);
   11720                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11721                         }
   11722                     }
   11723                     break;
   11724                 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
   11725 
   11726                     internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data,
   11727                                                                                       &(color_mdata.contentLightLevel));
   11728                     break;
   11729                 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI:
   11730                     internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data,
   11731                                                                                           &(color_mdata.masteringDisplayInfo));
   11732                     break;
   11733                 default:
   11734                     DEBUG_PRINT_LOW("Unrecognized extradata");
   11735                     goto unrecognized_extradata;
   11736             }
   11737             consumed_len += data->nSize;
   11738             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   11739         }
   11740         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   11741             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11742             append_frame_info_extradata(p_extra,
   11743                     num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   11744                     time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   11745                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   11746             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11747             if (p_client_extra) {
   11748                 append_frame_info_extradata(p_client_extra,
   11749                         num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   11750                         time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   11751                             p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   11752                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11753             }
   11754         }
   11755         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
   11756             append_frame_dimension_extradata(p_extra);
   11757             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11758             if (p_client_extra) {
   11759                 append_frame_dimension_extradata(p_client_extra);
   11760                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11761             }
   11762         }
   11763 
   11764         if(internal_hdr_info_changed_flag) {
   11765             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal");
   11766             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client");
   11767             memcpy(&m_color_mdata, &color_mdata, sizeof(ColorMetaData));
   11768             auto_lock lock(m_hdr_info_client_lock);
   11769             m_change_client_hdr_info = true;
   11770             if(!color_event) {
   11771                 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change");
   11772                 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   11773                            OMX_QTIIndexConfigDescribeHDRColorInfo,
   11774                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   11775             }
   11776         }
   11777 
   11778         if (m_enable_android_native_buffers) {
   11779             if (set_disp_color_aspects_only) {
   11780                 print_debug_hdr_color_info_mdata(&m_color_mdata);
   11781                 set_colormetadata_in_handle(&m_color_mdata, buf_index);
   11782             } else {
   11783                 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);
   11784                 set_colorspace_in_handle(color_space, buf_index);
   11785             }
   11786         }
   11787 
   11788     }
   11789 unrecognized_extradata:
   11790     if (client_extradata && p_extra) {
   11791         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11792         append_terminator_extradata(p_extra);
   11793         if (p_client_extra) {
   11794             append_terminator_extradata(p_client_extra);
   11795         }
   11796     }
   11797     if (secure_mode && p_extradata && m_other_extradata) {
   11798         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
   11799         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
   11800         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
   11801         ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
   11802         ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
   11803         ptr_extradatabuff->metadata_info.fd = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   11804         ptr_extradatabuff->metadata_info.offset = buf_index * drv_ctx.extradata_info.buffer_size;
   11805         ptr_extradatabuff->metadata_info.buffer_size = drv_ctx.extradata_info.size;
   11806     }
   11807     return;
   11808 }
   11809 
   11810 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata,
   11811         bool is_internal, bool enable)
   11812 {
   11813     OMX_ERRORTYPE ret = OMX_ErrorNone;
   11814     struct v4l2_control control;
   11815     if (m_state != OMX_StateLoaded) {
   11816         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   11817         return OMX_ErrorIncorrectStateOperation;
   11818     }
   11819     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
   11820             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
   11821 
   11822     if (!is_internal) {
   11823         if (enable)
   11824             client_extradata |= requested_extradata;
   11825         else
   11826             client_extradata = client_extradata & ~requested_extradata;
   11827     }
   11828 
   11829     if (enable) {
   11830         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   11831             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11832             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   11833             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11834                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   11835                         " Quality of interlaced clips might be impacted.");
   11836             }
   11837         }
   11838         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   11839             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11840             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   11841             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11842                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
   11843             }
   11844             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11845             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   11846             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11847                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
   11848             }
   11849             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11850             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   11851             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11852                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
   11853             }
   11854             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11855             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   11856             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11857                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11858             }
   11859             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11860             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
   11861             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11862                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11863             }
   11864             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   11865                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11866                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   11867                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11868                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11869                 }
   11870             }
   11871         }
   11872         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   11873             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11874             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   11875             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11876                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
   11877             }
   11878         }
   11879         if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
   11880             if (output_capability == V4L2_PIX_FMT_H264) {
   11881                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
   11882                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11883                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
   11884                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11885                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
   11886                 }
   11887             } else {
   11888                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
   11889             }
   11890         }
   11891         if (requested_extradata & OMX_QP_EXTRADATA) {
   11892             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11893             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   11894             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11895                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   11896             }
   11897         }
   11898         if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
   11899             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11900             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
   11901             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11902                 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
   11903             }
   11904         }
   11905         if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) {
   11906             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11907             control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
   11908             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11909                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
   11910             }
   11911         }
   11912         if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) {
   11913             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11914             control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI;
   11915             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11916                 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata");
   11917             }
   11918             client_extradata |= OMX_VQZIPSEI_EXTRADATA;
   11919 
   11920             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11921             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   11922             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11923                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   11924             }
   11925             client_extradata |= OMX_QP_EXTRADATA;
   11926         }
   11927         if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
   11928             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11929             control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
   11930             DEBUG_PRINT_LOW("Enable output crop extra data");
   11931             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11932                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
   11933             }
   11934         }
   11935         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
   11936             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11937             switch(output_capability) {
   11938                 case V4L2_PIX_FMT_H264:
   11939                 case V4L2_PIX_FMT_HEVC:
   11940                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
   11941                     break;
   11942                 case CODEC_TYPE_MPEG2:
   11943                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   11944                     break;
   11945                 case V4L2_PIX_FMT_VP8:
   11946                 case V4L2_PIX_FMT_VP9:
   11947                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
   11948                     break;
   11949                 case V4L2_PIX_FMT_VC1_ANNEX_G:
   11950                 case V4L2_PIX_FMT_VC1_ANNEX_L:
   11951                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP;
   11952                     break;
   11953                 default:
   11954                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
   11955                     return ret;
   11956             }
   11957 
   11958             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11959                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
   11960             }
   11961         }
   11962         if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) {
   11963             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11964             if (output_capability == V4L2_PIX_FMT_H264 ||
   11965                 output_capability == V4L2_PIX_FMT_HEVC) {
   11966                 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI;
   11967                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11968                     DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata");
   11969                 }
   11970                 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
   11971                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11972                     DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata");
   11973                 }
   11974             }
   11975         }
   11976     }
   11977     ret = get_buffer_req(&drv_ctx.op_buf);
   11978     return ret;
   11979 }
   11980 
   11981 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11982 {
   11983     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   11984     OMX_U8 *data_ptr = extra->data, data = 0;
   11985     while (byte_count < extra->nDataSize) {
   11986         data = *data_ptr;
   11987         while (data) {
   11988             num_MB += (data&0x01);
   11989             data >>= 1;
   11990         }
   11991         data_ptr++;
   11992         byte_count++;
   11993     }
   11994     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   11995             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   11996     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   11997 }
   11998 
   11999 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12000 {
   12001     if (!m_debug_extradata || !extra)
   12002         return;
   12003 
   12004 
   12005     DEBUG_PRINT_HIGH(
   12006             "============== Extra Data ==============\n"
   12007             "           Size: %u\n"
   12008             "        Version: %u\n"
   12009             "      PortIndex: %u\n"
   12010             "           Type: %x\n"
   12011             "       DataSize: %u",
   12012             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
   12013             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
   12014 
   12015     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   12016         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   12017         DEBUG_PRINT_HIGH(
   12018                 "------ Interlace Format ------\n"
   12019                 "                Size: %u\n"
   12020                 "             Version: %u\n"
   12021                 "           PortIndex: %u\n"
   12022                 " Is Interlace Format: %d\n"
   12023                 "   Interlace Formats: %u\n"
   12024                 "=========== End of Interlace ===========",
   12025                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
   12026                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
   12027     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   12028         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   12029 
   12030         DEBUG_PRINT_HIGH(
   12031                 "-------- Frame Format --------\n"
   12032                 "             Picture Type: %d\n"
   12033                 "           Interlace Type: %d\n"
   12034                 " Pan Scan Total Frame Num: %u\n"
   12035                 "   Concealed Macro Blocks: %u\n"
   12036                 "        Recovery SEI Flag: %u\n"
   12037                 "               frame rate: %u\n"
   12038                 "               Time Stamp: %llu\n"
   12039                 "           Aspect Ratio X: %u\n"
   12040                 "           Aspect Ratio Y: %u",
   12041                 fminfo->ePicType,
   12042                 fminfo->interlaceType,
   12043                 (unsigned int)fminfo->panScan.numWindows,
   12044                 (unsigned int)fminfo->nConcealedMacroblocks,
   12045                 (unsigned int)fminfo->nRecoverySeiFlag,
   12046                 (unsigned int)fminfo->nFrameRate,
   12047                 fminfo->nTimeStamp,
   12048                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
   12049                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
   12050 
   12051         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   12052             DEBUG_PRINT_HIGH(
   12053                     "------------------------------"
   12054                     "     Pan Scan Frame Num: %u\n"
   12055                     "            Rectangle x: %d\n"
   12056                     "            Rectangle y: %d\n"
   12057                     "           Rectangle dx: %d\n"
   12058                     "           Rectangle dy: %d",
   12059                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
   12060                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
   12061         }
   12062 
   12063         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   12064     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
   12065         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   12066         DEBUG_PRINT_HIGH(
   12067                 "------------------ Framepack Format ----------\n"
   12068                 "                           id: %u \n"
   12069                 "                  cancel_flag: %u \n"
   12070                 "                         type: %u \n"
   12071                 " quincunx_sampling_flagFormat: %u \n"
   12072                 "  content_interpretation_type: %u \n"
   12073                 "        spatial_flipping_flag: %u \n"
   12074                 "          frame0_flipped_flag: %u \n"
   12075                 "             field_views_flag: %u \n"
   12076                 " current_frame_is_frame0_flag: %u \n"
   12077                 "   frame0_self_contained_flag: %u \n"
   12078                 "   frame1_self_contained_flag: %u \n"
   12079                 "       frame0_grid_position_x: %u \n"
   12080                 "       frame0_grid_position_y: %u \n"
   12081                 "       frame1_grid_position_x: %u \n"
   12082                 "       frame1_grid_position_y: %u \n"
   12083                 "                reserved_byte: %u \n"
   12084                 "            repetition_period: %u \n"
   12085                 "               extension_flag: %u \n"
   12086                 "================== End of Framepack ===========",
   12087                 (unsigned int)framepack->id,
   12088                 (unsigned int)framepack->cancel_flag,
   12089                 (unsigned int)framepack->type,
   12090                 (unsigned int)framepack->quincunx_sampling_flag,
   12091                 (unsigned int)framepack->content_interpretation_type,
   12092                 (unsigned int)framepack->spatial_flipping_flag,
   12093                 (unsigned int)framepack->frame0_flipped_flag,
   12094                 (unsigned int)framepack->field_views_flag,
   12095                 (unsigned int)framepack->current_frame_is_frame0_flag,
   12096                 (unsigned int)framepack->frame0_self_contained_flag,
   12097                 (unsigned int)framepack->frame1_self_contained_flag,
   12098                 (unsigned int)framepack->frame0_grid_position_x,
   12099                 (unsigned int)framepack->frame0_grid_position_y,
   12100                 (unsigned int)framepack->frame1_grid_position_x,
   12101                 (unsigned int)framepack->frame1_grid_position_y,
   12102                 (unsigned int)framepack->reserved_byte,
   12103                 (unsigned int)framepack->repetition_period,
   12104                 (unsigned int)framepack->extension_flag);
   12105     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
   12106         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   12107         DEBUG_PRINT_HIGH(
   12108                 "---- QP (Frame quantization parameter) ----\n"
   12109                 "    Frame QP: %u \n"
   12110                 "================ End of QP ================\n",
   12111                 (unsigned int)qp->nQP);
   12112     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
   12113         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
   12114         DEBUG_PRINT_HIGH(
   12115                 "--------- Input bits information --------\n"
   12116                 "    Header bits: %u \n"
   12117                 "     Frame bits: %u \n"
   12118                 "===== End of Input bits information =====\n",
   12119                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
   12120     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
   12121         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
   12122         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
   12123         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
   12124         OMX_U32 i = 0;
   12125         DEBUG_PRINT_HIGH(
   12126                 "--------------  Userdata  -------------\n"
   12127                 "    Stream userdata type: %u\n"
   12128                 "          userdata size: %u\n"
   12129                 "    STREAM_USERDATA:",
   12130                 (unsigned int)userdata->type, (unsigned int)userdata_size);
   12131                 for (i = 0; i < userdata_size; i+=4) {
   12132                     DEBUG_PRINT_HIGH("        %x %x %x %x",
   12133                         data_ptr[i], data_ptr[i+1],
   12134                         data_ptr[i+2], data_ptr[i+3]);
   12135                 }
   12136         DEBUG_PRINT_HIGH(
   12137                 "=========== End of Userdata ===========");
   12138     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
   12139         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   12140         DEBUG_PRINT_HIGH(
   12141                 "--------------  VQZip  -------------\n"
   12142                 "    Size: %u\n",
   12143                 (unsigned int)vq->nSize);
   12144         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
   12145     } else if (extra->eType == OMX_ExtraDataNone) {
   12146         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   12147     } else {
   12148         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   12149     }
   12150 }
   12151 
   12152 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12153         OMX_U32 interlaced_format_type)
   12154 {
   12155     OMX_STREAMINTERLACEFORMAT *interlace_format;
   12156 
   12157     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   12158         return;
   12159     }
   12160     if (!extra) {
   12161        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
   12162        return;
   12163     }
   12164     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   12165     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12166     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12167     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   12168     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   12169     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   12170     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   12171     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   12172     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12173 
   12174     if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
   12175         interlace_format->bInterlaceFormat = OMX_FALSE;
   12176         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   12177         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   12178     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
   12179         interlace_format->bInterlaceFormat = OMX_TRUE;
   12180         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   12181         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   12182     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
   12183         interlace_format->bInterlaceFormat = OMX_TRUE;
   12184         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   12185         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   12186     } else {
   12187         //default case - set to progressive
   12188         interlace_format->bInterlaceFormat = OMX_FALSE;
   12189         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   12190         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   12191     }
   12192     print_debug_extradata(extra);
   12193 }
   12194 
   12195 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12196 {
   12197     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
   12198     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
   12199         return;
   12200     }
   12201     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
   12202     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12203     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12204     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
   12205     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
   12206     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
   12207     frame_dimension->nDecWidth = rectangle.nLeft;
   12208     frame_dimension->nDecHeight = rectangle.nTop;
   12209     frame_dimension->nActualWidth = rectangle.nWidth;
   12210     frame_dimension->nActualHeight = rectangle.nHeight;
   12211 }
   12212 
   12213 void omx_vdec::fill_aspect_ratio_info(
   12214         struct vdec_aspectratioinfo *aspect_ratio_info,
   12215         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   12216 {
   12217     m_extradata = frame_info;
   12218     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   12219     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   12220     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
   12221             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
   12222 }
   12223 
   12224 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12225         OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate,
   12226         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
   12227         struct vdec_aspectratioinfo *aspect_ratio_info)
   12228 {
   12229     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   12230     struct msm_vidc_panscan_window *panscan_window;
   12231     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   12232         return;
   12233     }
   12234     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   12235     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12236     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12237     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   12238     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   12239     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   12240     switch (picture_type) {
   12241         case PICTURE_TYPE_I:
   12242             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   12243             break;
   12244         case PICTURE_TYPE_P:
   12245             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   12246             break;
   12247         case PICTURE_TYPE_B:
   12248             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   12249             break;
   12250         default:
   12251             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   12252     }
   12253     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   12254         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   12255     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   12256         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   12257     else
   12258         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   12259     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   12260     frame_info->nConcealedMacroblocks = num_conceal_mb;
   12261     frame_info->nRecoverySeiFlag = recovery_sei_flag;
   12262     frame_info->nFrameRate = frame_rate;
   12263     frame_info->nTimeStamp = time_stamp;
   12264     frame_info->panScan.numWindows = 0;
   12265     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   12266         if (m_disp_hor_size && m_disp_vert_size) {
   12267             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   12268             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   12269         } else {
   12270             frame_info->displayAspectRatio.displayHorizontalSize = 0;
   12271             frame_info->displayAspectRatio.displayVerticalSize = 0;
   12272         }
   12273     }
   12274 
   12275     if (panscan_payload) {
   12276         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   12277         panscan_window = &panscan_payload->wnd[0];
   12278         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   12279             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   12280             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   12281             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   12282             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   12283             panscan_window++;
   12284         }
   12285     }
   12286     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   12287     print_debug_extradata(extra);
   12288 }
   12289 
   12290 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12291 {
   12292     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   12293     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   12294     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12295     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12296     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   12297     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   12298     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
   12299     *portDefn = m_port_def;
   12300     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
   12301             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
   12302             (unsigned int)portDefn->format.video.nFrameWidth,
   12303             (unsigned int)portDefn->format.video.nStride,
   12304             (unsigned int)portDefn->format.video.nSliceHeight);
   12305 }
   12306 
   12307 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12308         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
   12309 {
   12310     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
   12311     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
   12312         DEBUG_PRINT_ERROR("frame packing size mismatch");
   12313         return;
   12314     }
   12315     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
   12316     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12317     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12318     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
   12319     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   12320     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   12321     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   12322     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
   12323     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12324     memcpy(&framepack->id, s3d_frame_packing_payload,
   12325         sizeof(struct msm_vidc_s3d_frame_packing_payload));
   12326     memcpy(&m_frame_pack_arrangement, framepack,
   12327         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   12328     print_debug_extradata(extra);
   12329 }
   12330 
   12331 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12332             struct msm_vidc_frame_qp_payload *qp_payload)
   12333 {
   12334     OMX_QCOM_EXTRADATA_QP * qp = NULL;
   12335     if (!qp_payload) {
   12336         DEBUG_PRINT_ERROR("QP payload is NULL");
   12337         return;
   12338     }
   12339     extra->nSize = OMX_QP_EXTRADATA_SIZE;
   12340     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12341     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12342     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
   12343     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
   12344     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   12345     qp->nQP = qp_payload->frame_qp;
   12346     print_debug_extradata(extra);
   12347 }
   12348 
   12349 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12350             struct msm_vidc_frame_bits_info_payload *bits_payload)
   12351 {
   12352     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
   12353     if (!bits_payload) {
   12354         DEBUG_PRINT_ERROR("bits info payload is NULL");
   12355         return;
   12356     }
   12357     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
   12358     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12359     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12360     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
   12361     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
   12362     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
   12363     bits->frame_bits = bits_payload->frame_bits;
   12364     bits->header_bits = bits_payload->header_bits;
   12365     print_debug_extradata(extra);
   12366 }
   12367 
   12368 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12369             OMX_OTHER_EXTRADATATYPE *p_user)
   12370 {
   12371     int userdata_size = 0;
   12372     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
   12373     userdata_payload =
   12374         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
   12375     userdata_size = p_user->nDataSize;
   12376     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
   12377     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12378     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12379     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
   12380     extra->nDataSize = userdata_size;
   12381     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
   12382         memcpy(extra->data, p_user->data, extra->nDataSize);
   12383     print_debug_extradata(extra);
   12384 }
   12385 
   12386 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12387 {
   12388     if (!client_extradata) {
   12389         return;
   12390     }
   12391     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   12392     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12393     extra->eType = OMX_ExtraDataNone;
   12394     extra->nDataSize = 0;
   12395     extra->data[0] = 0;
   12396 
   12397     print_debug_extradata(extra);
   12398 }
   12399 
   12400 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12401         struct msm_vidc_vqzip_sei_payload *vqzip_payload)
   12402 {
   12403     OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL;
   12404 
   12405     extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size;
   12406     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12407     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12408     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI;
   12409     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size;
   12410 
   12411     vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   12412     vq->nSize = vqzip_payload->size;
   12413     memcpy(vq->data, vqzip_payload->data, vqzip_payload->size);
   12414 
   12415     print_debug_extradata(extra);
   12416 }
   12417 
   12418 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   12419 {
   12420     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12421     if (index >= drv_ctx.ip_buf.actualcount) {
   12422         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
   12423         return OMX_ErrorInsufficientResources;
   12424     }
   12425     if (m_desc_buffer_ptr == NULL) {
   12426         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   12427                     calloc( (sizeof(desc_buffer_hdr)),
   12428                             drv_ctx.ip_buf.actualcount);
   12429         if (m_desc_buffer_ptr == NULL) {
   12430             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
   12431             return OMX_ErrorInsufficientResources;
   12432         }
   12433     }
   12434 
   12435     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   12436     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   12437         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
   12438         return OMX_ErrorInsufficientResources;
   12439     }
   12440 
   12441     return eRet;
   12442 }
   12443 
   12444 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   12445 {
   12446     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
   12447     if (m_demux_entries < 8192) {
   12448         m_demux_offsets[m_demux_entries++] = address_offset;
   12449     }
   12450     return;
   12451 }
   12452 
   12453 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   12454 {
   12455     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   12456     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   12457     OMX_U32 index = 0;
   12458 
   12459     m_demux_entries = 0;
   12460 
   12461     while (index < bytes_to_parse) {
   12462         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   12463                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   12464                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   12465                  (buf[index+2] == 0x01)) ) {
   12466             //Found start code, insert address offset
   12467             insert_demux_addr_offset(index);
   12468             if (buf[index+2] == 0x01) // 3 byte start code
   12469                 index += 3;
   12470             else                      //4 byte start code
   12471                 index += 4;
   12472         } else
   12473             index++;
   12474     }
   12475     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
   12476     return;
   12477 }
   12478 
   12479 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   12480 {
   12481     //fix this, handle 3 byte start code, vc1 terminator entry
   12482     OMX_U8 *p_demux_data = NULL;
   12483     OMX_U32 desc_data = 0;
   12484     OMX_U32 start_addr = 0;
   12485     OMX_U32 nal_size = 0;
   12486     OMX_U32 suffix_byte = 0;
   12487     OMX_U32 demux_index = 0;
   12488     OMX_U32 buffer_index = 0;
   12489 
   12490     if (m_desc_buffer_ptr == NULL) {
   12491         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   12492         return OMX_ErrorBadParameter;
   12493     }
   12494 
   12495     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   12496     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   12497         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
   12498         return OMX_ErrorBadParameter;
   12499     }
   12500 
   12501     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   12502 
   12503     if ( ((OMX_U8*)p_demux_data == NULL) ||
   12504             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   12505         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   12506         return OMX_ErrorBadParameter;
   12507     } else {
   12508         for (; demux_index < m_demux_entries; demux_index++) {
   12509             desc_data = 0;
   12510             start_addr = m_demux_offsets[demux_index];
   12511             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   12512                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   12513             } else {
   12514                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   12515             }
   12516             if (demux_index < (m_demux_entries - 1)) {
   12517                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   12518             } else {
   12519                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   12520             }
   12521             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
   12522                     (unsigned int)start_addr,
   12523                     (unsigned int)suffix_byte,
   12524                     (unsigned int)nal_size,
   12525                     (unsigned int)demux_index);
   12526             desc_data = (start_addr >> 3) << 1;
   12527             desc_data |= (start_addr & 7) << 21;
   12528             desc_data |= suffix_byte << 24;
   12529 
   12530             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   12531             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   12532             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   12533             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   12534 
   12535             p_demux_data += 16;
   12536         }
   12537         if (codec_type_parse == CODEC_TYPE_VC1) {
   12538             DEBUG_PRINT_LOW("VC1 terminator entry");
   12539             desc_data = 0;
   12540             desc_data = 0x82 << 24;
   12541             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   12542             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   12543             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   12544             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   12545             p_demux_data += 16;
   12546             m_demux_entries++;
   12547         }
   12548         //Add zero word to indicate end of descriptors
   12549         memset(p_demux_data, 0, sizeof(OMX_U32));
   12550 
   12551         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   12552         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
   12553     }
   12554     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   12555     m_demux_entries = 0;
   12556     DEBUG_PRINT_LOW("Demux table complete!");
   12557     return OMX_ErrorNone;
   12558 }
   12559 
   12560 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level)
   12561 {
   12562     struct v4l2_control control;
   12563     char property_value[PROPERTY_VALUE_MAX] = {0};
   12564 
   12565     property_get("vendor.vidc.debug.turbo", property_value, "0");
   12566     memset(&control, 0, sizeof(v4l2_control));
   12567     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   12568     switch (perf_level) {
   12569     case VIDC_NOMINAL:
   12570         if (atoi(property_value))
   12571             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   12572         else
   12573             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   12574         break;
   12575     case VIDC_TURBO:
   12576         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   12577         break;
   12578      default:
   12579         DEBUG_PRINT_ERROR("Requested PERF level not supported");
   12580         break;
   12581     }
   12582     if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig)
   12583         return;
   12584 
   12585     DEBUG_PRINT_HIGH("changing performance level to %d", control.value);
   12586     if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   12587         current_perf_level = control.value;
   12588     } else {
   12589         DEBUG_PRINT_ERROR("Failed to set PERF level");
   12590     }
   12591 }
   12592 
   12593 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   12594 {
   12595     enabled = false;
   12596     omx = NULL;
   12597     init_members();
   12598     ColorFormat = OMX_COLOR_FormatMax;
   12599     dest_format = YCbCr420P;
   12600     m_c2d_width = 0;
   12601     m_c2d_height = 0;
   12602 }
   12603 
   12604 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   12605 {
   12606     omx = reinterpret_cast<omx_vdec*>(client);
   12607 }
   12608 
   12609 void omx_vdec::allocate_color_convert_buf::init_members()
   12610 {
   12611     allocated_count = 0;
   12612     buffer_size_req = 0;
   12613     buffer_alignment_req = 0;
   12614     m_c2d_width = m_c2d_height = 0;
   12615     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   12616     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   12617     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   12618     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   12619 #ifdef USE_ION
   12620     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   12621 #endif
   12622     for (int i = 0; i < MAX_COUNT; i++)
   12623         pmem_fd[i] = -1;
   12624 }
   12625 
   12626 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   12627 {
   12628     c2d.destroy();
   12629 }
   12630 
   12631 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   12632 {
   12633     bool status = true;
   12634     unsigned int src_size = 0, destination_size = 0;
   12635     unsigned int height, width;
   12636     struct v4l2_format fmt;
   12637     OMX_COLOR_FORMATTYPE drv_color_format;
   12638 
   12639     if (!omx) {
   12640         DEBUG_PRINT_ERROR("Invalid client in color convert");
   12641         return false;
   12642     }
   12643     if (!enabled) {
   12644         DEBUG_PRINT_HIGH("No color conversion required");
   12645         return status;
   12646     }
   12647     pthread_mutex_lock(&omx->c_lock);
   12648 
   12649     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   12650     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   12651     fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
   12652     ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   12653     width = fmt.fmt.pix_mp.width;
   12654     height =  fmt.fmt.pix_mp.height;
   12655 
   12656     bool resolution_upgrade = (height > m_c2d_height ||
   12657             width > m_c2d_width);
   12658     if (resolution_upgrade) {
   12659         // resolution upgraded ? ensure we are yet to allocate;
   12660         // failing which, c2d buffers will never be reallocated and bad things will happen
   12661         if (allocated_count > 0) {
   12662             DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
   12663                     allocated_count);
   12664             status = false;
   12665             goto fail_update_buf_req;
   12666         }
   12667     }
   12668 
   12669     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   12670             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   12671         DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
   12672         status = false;
   12673         goto fail_update_buf_req;
   12674     }
   12675     c2d.close();
   12676     status = c2d.open(height,
   12677             width,
   12678             NV12_128m,dest_format);
   12679     if (status) {
   12680         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   12681         if (status)
   12682             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   12683     }
   12684     if (status) {
   12685         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   12686                 !destination_size) {
   12687             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
   12688                     "driver size %u destination size %d",
   12689                     src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
   12690                     destination_size);
   12691             status = false;
   12692             c2d.close();
   12693             buffer_size_req = 0;
   12694             // TODO: make this fatal. Driver is not supposed to quote size
   12695             //  smaller than what C2D needs !!
   12696         } else {
   12697             buffer_size_req = destination_size;
   12698             m_c2d_height = height;
   12699             m_c2d_width = width;
   12700         }
   12701     }
   12702 fail_update_buf_req:
   12703     pthread_mutex_unlock(&omx->c_lock);
   12704     return status;
   12705 }
   12706 
   12707 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   12708         OMX_COLOR_FORMATTYPE dest_color_format)
   12709 {
   12710     bool status = true, drv_colorformat_c2d_enable = false;
   12711     bool dest_color_format_c2d_enable = false;
   12712     OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused;
   12713     if (!omx) {
   12714         DEBUG_PRINT_ERROR("Invalid client in color convert");
   12715         return false;
   12716     }
   12717     pthread_mutex_lock(&omx->c_lock);
   12718     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   12719         if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   12720             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12721                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   12722         else
   12723             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12724                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   12725      else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   12726          drv_color_format = (OMX_COLOR_FORMATTYPE)
   12727                   QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   12728      } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   12729             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12730                     QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
   12731      } else {
   12732         DEBUG_PRINT_ERROR("Incorrect color format");
   12733         status = false;
   12734     }
   12735     drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) &&
   12736         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12737                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
   12738         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12739                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
   12740         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12741                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
   12742 
   12743     dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
   12744             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
   12745             (dest_color_format != (OMX_COLOR_FORMATTYPE)
   12746                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
   12747 
   12748     if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) {
   12749         DEBUG_PRINT_LOW("Enabling C2D");
   12750         if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
   12751            (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
   12752             DEBUG_PRINT_ERROR("Unsupported color format for c2d");
   12753             status = false;
   12754         } else {
   12755             ColorFormat = dest_color_format;
   12756             dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
   12757                     YCbCr420P : YCbCr420SP;
   12758             if (enabled)
   12759                 c2d.destroy();
   12760             enabled = false;
   12761             if (!c2d.init()) {
   12762                 DEBUG_PRINT_ERROR("open failed for c2d");
   12763                 status = false;
   12764             } else
   12765                 enabled = true;
   12766         }
   12767     } else {
   12768         if (enabled)
   12769             c2d.destroy();
   12770         enabled = false;
   12771     }
   12772     pthread_mutex_unlock(&omx->c_lock);
   12773     return status;
   12774 }
   12775 
   12776 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   12777 {
   12778     if (!omx) {
   12779         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12780         return NULL;
   12781     }
   12782     if (!enabled)
   12783         return omx->m_out_mem_ptr;
   12784     return m_out_mem_ptr_client;
   12785 }
   12786 
   12787     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   12788 (OMX_BUFFERHEADERTYPE *bufadd)
   12789 {
   12790     if (!omx) {
   12791         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12792         return NULL;
   12793     }
   12794     if (!enabled)
   12795         return bufadd;
   12796 
   12797     unsigned index = 0;
   12798     index = bufadd - omx->m_out_mem_ptr;
   12799     if (index < omx->drv_ctx.op_buf.actualcount) {
   12800         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   12801         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   12802         bool status;
   12803         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   12804             pthread_mutex_lock(&omx->c_lock);
   12805             cache_clean_buffer(index);
   12806             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   12807                     omx->drv_ctx.op_buf_map_info[index].base_address, bufadd->pBuffer, pmem_fd[index],
   12808                     pmem_baseaddress[index], pmem_baseaddress[index]);
   12809             if (!status) {
   12810                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
   12811                 m_out_mem_ptr_client[index].nFilledLen = 0;
   12812                 pthread_mutex_unlock(&omx->c_lock);
   12813                 return &m_out_mem_ptr_client[index];
   12814             } else {
   12815                 unsigned int filledLen = 0;
   12816                 c2d.get_output_filled_length(filledLen);
   12817                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
   12818                 cache_clean_invalidate_buffer(index);
   12819             }
   12820             pthread_mutex_unlock(&omx->c_lock);
   12821         } else
   12822             m_out_mem_ptr_client[index].nFilledLen = 0;
   12823         return &m_out_mem_ptr_client[index];
   12824     }
   12825     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
   12826     return NULL;
   12827 }
   12828 
   12829     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   12830 (OMX_BUFFERHEADERTYPE *bufadd)
   12831 {
   12832     if (!omx) {
   12833         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12834         return NULL;
   12835     }
   12836     if (!enabled)
   12837         return bufadd;
   12838     unsigned index = 0;
   12839     index = bufadd - m_out_mem_ptr_client;
   12840     if (index < omx->drv_ctx.op_buf.actualcount) {
   12841         return &omx->m_out_mem_ptr[index];
   12842     }
   12843     DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
   12844     return NULL;
   12845 }
   12846     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   12847 (unsigned int &buffer_size)
   12848 {
   12849     bool status = true;
   12850     pthread_mutex_lock(&omx->c_lock);
   12851     if (!enabled)
   12852         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   12853     else {
   12854         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   12855             DEBUG_PRINT_ERROR("Get buffer size failed");
   12856             status = false;
   12857             goto fail_get_buffer_size;
   12858         }
   12859     }
   12860 fail_get_buffer_size:
   12861     pthread_mutex_unlock(&omx->c_lock);
   12862     return status;
   12863 }
   12864 
   12865 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
   12866         OMX_U32 buffer_size, OMX_U32 actual_count) {
   12867     OMX_U32 expectedSize = enabled ? buffer_size_req : omx->drv_ctx.op_buf.buffer_size;
   12868 
   12869     if (buffer_size < expectedSize) {
   12870         DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
   12871                 buffer_size, expectedSize);
   12872         return OMX_ErrorBadParameter;
   12873     }
   12874     if (actual_count < omx->drv_ctx.op_buf.actualcount) {
   12875         DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
   12876                 actual_count, omx->drv_ctx.op_buf.actualcount);
   12877         return OMX_ErrorBadParameter;
   12878     }
   12879 
   12880     bool reqs_updated = false;
   12881     if (enabled) {
   12882         // disallow changing buffer size/count while we have active allocated buffers
   12883         if (allocated_count > 0) {
   12884             DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
   12885                     buffer_size_req, buffer_size, allocated_count);
   12886             return OMX_ErrorInvalidState;
   12887         }
   12888 
   12889         buffer_size_req = buffer_size;
   12890     } else {
   12891         if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
   12892             omx->drv_ctx.op_buf.buffer_size = buffer_size;
   12893             reqs_updated = true;
   12894         }
   12895     }
   12896 
   12897     if (actual_count > omx->drv_ctx.op_buf.actualcount) {
   12898         omx->drv_ctx.op_buf.actualcount = actual_count;
   12899         reqs_updated = true;
   12900     }
   12901 
   12902     if (reqs_updated) {
   12903         omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
   12904         omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
   12905                 omx->drv_ctx.extradata_info.buffer_size;
   12906         return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
   12907     }
   12908     return OMX_ErrorNone;
   12909 }
   12910 
   12911 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   12912         OMX_BUFFERHEADERTYPE *bufhdr)
   12913 {
   12914     unsigned int index = 0;
   12915 
   12916     if (!enabled)
   12917         return omx->free_output_buffer(bufhdr);
   12918     if (enabled && omx->is_component_secure())
   12919         return OMX_ErrorNone;
   12920     if (!allocated_count || !bufhdr) {
   12921         DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
   12922         return OMX_ErrorBadParameter;
   12923     }
   12924     index = bufhdr - m_out_mem_ptr_client;
   12925     if (index >= omx->drv_ctx.op_buf.actualcount) {
   12926         DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
   12927         return OMX_ErrorBadParameter;
   12928     }
   12929     if (pmem_fd[index] >= 0) {
   12930         munmap(pmem_baseaddress[index], buffer_size_req);
   12931         close(pmem_fd[index]);
   12932     }
   12933     pmem_fd[index] = -1;
   12934 #ifdef USE_ION
   12935     omx->free_ion_memory(&op_buf_ion_info[index]);
   12936 #endif
   12937     if (allocated_count > 0)
   12938         allocated_count--;
   12939     else
   12940         allocated_count = 0;
   12941     if (!allocated_count) {
   12942         pthread_mutex_lock(&omx->c_lock);
   12943         c2d.close();
   12944         init_members();
   12945         pthread_mutex_unlock(&omx->c_lock);
   12946     }
   12947     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   12948 }
   12949 
   12950 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   12951         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   12952 {
   12953     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12954     if (!enabled) {
   12955         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   12956         return eRet;
   12957     }
   12958     if (enabled && omx->is_component_secure()) {
   12959         DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
   12960                 omx->is_component_secure());
   12961         return OMX_ErrorUnsupportedSetting;
   12962     }
   12963     if (!bufferHdr || bytes > buffer_size_req) {
   12964         DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   12965         DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
   12966                 (unsigned int)buffer_size_req, (unsigned int)bytes);
   12967         return OMX_ErrorBadParameter;
   12968     }
   12969     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   12970         DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
   12971         return OMX_ErrorInsufficientResources;
   12972     }
   12973     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   12974     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   12975             port,appData,omx->drv_ctx.op_buf.buffer_size);
   12976     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   12977         DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
   12978         return eRet;
   12979     }
   12980     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   12981             (int)omx->drv_ctx.op_buf.actualcount) {
   12982         DEBUG_PRINT_ERROR("Invalid header index %ld",
   12983                (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
   12984         return OMX_ErrorUndefined;
   12985     }
   12986     unsigned int i = allocated_count;
   12987 #ifdef USE_ION
   12988     // Allocate color-conversion buffers as cached to improve software-reading
   12989     // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
   12990     // cache invalidation.
   12991     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   12992             buffer_size_req,buffer_alignment_req,
   12993             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   12994             ION_FLAG_CACHED);
   12995     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   12996     if (op_buf_ion_info[i].ion_device_fd < 0) {
   12997         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
   12998         return OMX_ErrorInsufficientResources;
   12999     }
   13000     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   13001             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   13002 
   13003     if (pmem_baseaddress[i] == MAP_FAILED) {
   13004         DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
   13005         close(pmem_fd[i]);
   13006         omx->free_ion_memory(&op_buf_ion_info[i]);
   13007         return OMX_ErrorInsufficientResources;
   13008     }
   13009 #endif
   13010     m_pmem_info_client[i].offset = 0;
   13011     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   13012     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   13013     m_platform_list_client[i].nEntries = 1;
   13014     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   13015     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   13016     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   13017     m_out_mem_ptr_client[i].nFilledLen = 0;
   13018     m_out_mem_ptr_client[i].nFlags = 0;
   13019     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   13020     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   13021     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   13022     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   13023     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   13024     m_out_mem_ptr_client[i].pAppPrivate = appData;
   13025     *bufferHdr = &m_out_mem_ptr_client[i];
   13026     DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr);
   13027     allocated_count++;
   13028     return eRet;
   13029 }
   13030 
   13031 bool omx_vdec::is_component_secure()
   13032 {
   13033     return secure_mode;
   13034 }
   13035 
   13036 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   13037 {
   13038     bool status = true;
   13039     if (!enabled) {
   13040         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   13041             if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   13042                     dest_color_format = (OMX_COLOR_FORMATTYPE)
   13043                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   13044                 else
   13045                     dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   13046         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){
   13047              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   13048         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC){
   13049              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
   13050         } else
   13051             status = false;
   13052     } else {
   13053         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
   13054             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   13055             dest_color_format = ColorFormat;
   13056         } else
   13057             status = false;
   13058     }
   13059     return status;
   13060 }
   13061 
   13062 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
   13063         unsigned int index, unsigned int cmd)
   13064 {
   13065     if (!enabled) {
   13066         return OMX_ErrorNone;
   13067     }
   13068 
   13069     if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
   13070         DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
   13071         return OMX_ErrorBadParameter;
   13072     }
   13073 
   13074     struct ion_flush_data flush_data;
   13075     struct ion_custom_data custom_data;
   13076 
   13077     memset(&flush_data, 0x0, sizeof(flush_data));
   13078     memset(&custom_data, 0x0, sizeof(custom_data));
   13079 
   13080     flush_data.vaddr = pmem_baseaddress[index];
   13081     flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
   13082     flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
   13083     flush_data.length = buffer_size_req;
   13084     custom_data.cmd = cmd;
   13085     custom_data.arg = (unsigned long)&flush_data;
   13086 
   13087     DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
   13088             (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   13089             flush_data.fd, flush_data.handle, flush_data.vaddr,
   13090             flush_data.length);
   13091     int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
   13092     if (ret < 0) {
   13093         DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
   13094                 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   13095                 strerror(errno));
   13096         return OMX_ErrorUndefined;
   13097     }
   13098     return OMX_ErrorNone;
   13099 }
   13100 
   13101 void omx_vdec::buf_ref_add(int nPortIndex)
   13102 {
   13103     unsigned long i = 0;
   13104     bool buf_present = false;
   13105     long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   13106     OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   13107 
   13108     if (!dynamic_buf_mode || !out_dynamic_list) {
   13109         return;
   13110     }
   13111 
   13112     pthread_mutex_lock(&m_lock);
   13113     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13114         //check the buffer fd, offset, uv addr with list contents
   13115         //If present increment reference.
   13116         if ((out_dynamic_list[i].fd == fd) &&
   13117             (out_dynamic_list[i].offset == offset)) {
   13118                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
   13119                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13120                if (!secure_mode) {
   13121                    drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr;
   13122                }
   13123                buf_present = true;
   13124                break;
   13125         }
   13126     }
   13127     if (!buf_present) {
   13128         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13129             //search for a entry to insert details of the new buffer
   13130             if (out_dynamic_list[i].dup_fd < 0) {
   13131                 out_dynamic_list[i].fd = fd;
   13132                 out_dynamic_list[i].offset = offset;
   13133                 out_dynamic_list[i].dup_fd = dup(fd);
   13134                 out_dynamic_list[i].ref_count++;
   13135                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
   13136                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13137 
   13138                 if (!secure_mode) {
   13139                     drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   13140                             (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len,
   13141                                           PROT_READ|PROT_WRITE, MAP_SHARED,
   13142                                           drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   13143                     //mmap returns (void *)-1 on failure and sets error code in errno.
   13144                     if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) {
   13145                         DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno);
   13146                         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL;
   13147                         break;
   13148                     }
   13149                     out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr;
   13150                     out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len;
   13151                     DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   13152                 }
   13153                 break;
   13154             }
   13155         }
   13156     }
   13157    pthread_mutex_unlock(&m_lock);
   13158 }
   13159 
   13160 void omx_vdec::buf_ref_remove()
   13161 {
   13162     unsigned long i = 0;
   13163 
   13164     if (!dynamic_buf_mode || !out_dynamic_list) {
   13165         return;
   13166     }
   13167 
   13168     pthread_mutex_lock(&m_lock);
   13169     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13170         if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) {
   13171             DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   13172             munmap(out_dynamic_list[i].buffaddr,
   13173                         out_dynamic_list[i].mapped_size);
   13174         }
   13175 
   13176          DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
   13177                  (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13178          close(out_dynamic_list[i].dup_fd);
   13179          out_dynamic_list[i].dup_fd = -1;
   13180     }
   13181     pthread_mutex_unlock(&m_lock);
   13182 
   13183     if (out_dynamic_list) {
   13184         free(out_dynamic_list);
   13185         out_dynamic_list = NULL;
   13186     }
   13187 }
   13188 
   13189 #ifdef _MSM8974_
   13190 void omx_vdec::send_codec_config() {
   13191     if (codec_config_flag) {
   13192         unsigned long p1 = 0; // Parameter - 1
   13193         unsigned long p2 = 0; // Parameter - 2
   13194         unsigned long ident = 0;
   13195         pthread_mutex_lock(&m_lock);
   13196         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   13197         while (m_etb_q.m_size) {
   13198             m_etb_q.pop_entry(&p1,&p2,&ident);
   13199             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   13200                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   13201                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   13202                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   13203                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   13204                         omx_report_error();
   13205                     }
   13206                 } else {
   13207                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   13208                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   13209                 }
   13210             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   13211                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   13212                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   13213                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   13214                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   13215                         omx_report_error ();
   13216                     }
   13217                 } else {
   13218                     pending_input_buffers++;
   13219                     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   13220                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   13221                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   13222                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   13223                 }
   13224             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   13225                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   13226                         (OMX_BUFFERHEADERTYPE *)p1);
   13227                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   13228             }
   13229         }
   13230         pthread_mutex_unlock(&m_lock);
   13231     }
   13232 }
   13233 #endif
   13234 
   13235 omx_vdec::perf_control::perf_control()
   13236 {
   13237     m_perf_lib = NULL;
   13238     m_perf_handle = 0;
   13239     m_perf_lock_acquire = NULL;
   13240     m_perf_lock_release = NULL;
   13241 }
   13242 
   13243 omx_vdec::perf_control::~perf_control()
   13244 {
   13245     if (m_perf_handle != 0 && m_perf_lock_release) {
   13246         DEBUG_PRINT_LOW("NOTE2: release perf lock");
   13247         m_perf_lock_release(m_perf_handle);
   13248     }
   13249     if (m_perf_lib) {
   13250         dlclose(m_perf_lib);
   13251     }
   13252 }
   13253 
   13254 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0};
   13255 
   13256 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock;
   13257 
   13258 void omx_vdec::perf_control::send_hint_to_mpctl(bool state)
   13259 {
   13260     if (load_lib() == false) {
   13261        return;
   13262     }
   13263     m_perf_lock.lock();
   13264     /* 0x4401 maps to video decode playback hint
   13265      * in perflock, enum number is 44 and state
   13266      * being sent on perflock acquire is 01 (true)
   13267      */
   13268     int arg = 0x4401;
   13269 
   13270     if (state == true) {
   13271         mpctl_obj.vid_inst_count++;
   13272     } else if (state == false) {
   13273         mpctl_obj.vid_inst_count--;
   13274     }
   13275 
   13276     if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) {
   13277         mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
   13278         mpctl_obj.vid_acquired = true;
   13279         DEBUG_PRINT_INFO("Video slvp perflock acquired");
   13280     } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) {
   13281         m_perf_lock_release(mpctl_obj.vid_disp_handle);
   13282         mpctl_obj.vid_acquired = false;
   13283         DEBUG_PRINT_INFO("Video slvp perflock released");
   13284     }
   13285     m_perf_lock.unlock();
   13286 }
   13287 
   13288 void omx_vdec::perf_control::request_cores(int frame_duration_us)
   13289 {
   13290     if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
   13291         return;
   13292     }
   13293     bool retVal = load_lib();
   13294     if (retVal && m_perf_lock_acquire && m_perf_handle == 0) {
   13295         int arg = 0x700 /*base value*/ + 2 /*cores*/;
   13296         m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
   13297         if (m_perf_handle) {
   13298             DEBUG_PRINT_HIGH("perf lock acquired");
   13299         }
   13300     }
   13301 }
   13302 
   13303 bool omx_vdec::perf_control::load_lib()
   13304 {
   13305     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
   13306     if (m_perf_lib)
   13307         return true;
   13308 
   13309     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
   13310         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
   13311         goto handle_err;
   13312     }
   13313 
   13314     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
   13315         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
   13316         goto handle_err;
   13317     } else {
   13318         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
   13319         if (m_perf_lock_acquire == NULL) {
   13320             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
   13321             goto handle_err;
   13322         }
   13323         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
   13324         if (m_perf_lock_release == NULL) {
   13325             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
   13326             goto handle_err;
   13327         }
   13328     }
   13329     return true;
   13330 
   13331 handle_err:
   13332     if (m_perf_lib) {
   13333         dlclose(m_perf_lib);
   13334     }
   13335     m_perf_lib = NULL;
   13336     return false;
   13337 }
   13338 
   13339 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
   13340                             unsigned long nMaxFrameHeight)
   13341 {
   13342 
   13343     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   13344     int ret = 0;
   13345     unsigned long min_res_buf_count = 0;
   13346 
   13347     eRet = enable_smoothstreaming();
   13348     if (eRet != OMX_ErrorNone) {
   13349          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
   13350          return eRet;
   13351      }
   13352 
   13353      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
   13354              nMaxFrameWidth,
   13355              nMaxFrameHeight);
   13356      m_smoothstreaming_mode = true;
   13357      m_smoothstreaming_width = nMaxFrameWidth;
   13358      m_smoothstreaming_height = nMaxFrameHeight;
   13359 
   13360      //Get upper limit buffer count for min supported resolution
   13361      struct v4l2_format fmt;
   13362      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   13363      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
   13364      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
   13365      fmt.fmt.pix_mp.pixelformat = output_capability;
   13366 
   13367      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   13368      if (ret) {
   13369          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
   13370                            m_decoder_capability.min_height,
   13371                            m_decoder_capability.min_width);
   13372          return OMX_ErrorUnsupportedSetting;
   13373      }
   13374 
   13375      eRet = get_buffer_req(&drv_ctx.op_buf);
   13376      if (eRet != OMX_ErrorNone) {
   13377          DEBUG_PRINT_ERROR("failed to get_buffer_req");
   13378          return eRet;
   13379      }
   13380 
   13381      min_res_buf_count = drv_ctx.op_buf.mincount;
   13382      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
   13383                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
   13384 
   13385      m_extradata_info.output_crop_rect.nLeft = 0;
   13386      m_extradata_info.output_crop_rect.nTop = 0;
   13387      m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width;
   13388      m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height;
   13389 
   13390      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
   13391                        m_smoothstreaming_width, m_smoothstreaming_height);
   13392      eRet = is_video_session_supported();
   13393      if (eRet != OMX_ErrorNone) {
   13394          DEBUG_PRINT_ERROR("video session is not supported");
   13395          return eRet;
   13396      }
   13397 
   13398      //Get upper limit buffer size for max smooth streaming resolution set
   13399      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   13400      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   13401      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   13402      fmt.fmt.pix_mp.pixelformat = output_capability;
   13403      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   13404      if (ret) {
   13405          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
   13406          return OMX_ErrorUnsupportedSetting;
   13407      }
   13408 
   13409      eRet = get_buffer_req(&drv_ctx.op_buf);
   13410      if (eRet != OMX_ErrorNone) {
   13411          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
   13412          return eRet;
   13413      }
   13414      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
   13415                      (unsigned int)drv_ctx.op_buf.buffer_size);
   13416 
   13417      drv_ctx.op_buf.mincount = min_res_buf_count;
   13418      drv_ctx.op_buf.actualcount = min_res_buf_count;
   13419      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
   13420      eRet = set_buffer_req(&drv_ctx.op_buf);
   13421      if (eRet != OMX_ErrorNone) {
   13422          DEBUG_PRINT_ERROR("failed to set_buffer_req");
   13423          return eRet;
   13424      }
   13425 
   13426      eRet = get_buffer_req(&drv_ctx.op_buf);
   13427      if (eRet != OMX_ErrorNone) {
   13428          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
   13429          return eRet;
   13430      }
   13431      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
   13432                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
   13433      return eRet;
   13434 }
   13435 
   13436 //static
   13437 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
   13438 
   13439 #ifndef FLEXYUV_SUPPORTED
   13440     return OMX_ErrorUndefined;
   13441 #else
   13442 
   13443     if (pParam == NULL) {
   13444         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
   13445         return OMX_ErrorBadParameter;
   13446     }
   13447 
   13448     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
   13449 
   13450     MediaImage *img = &(params->sMediaImage);
   13451     switch(params->eColorFormat) {
   13452         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   13453         {
   13454             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   13455             img->mNumPlanes = 3;
   13456             // mWidth and mHeight represent the W x H of the largest plane
   13457             // In our case, this happens to be the Stride x Scanlines of Y plane
   13458             img->mWidth = params->nFrameWidth;
   13459             img->mHeight = params->nFrameHeight;
   13460             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13461             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
   13462             img->mBitDepth = 8;
   13463             //Plane 0 (Y)
   13464             img->mPlane[MediaImage::Y].mOffset = 0;
   13465             img->mPlane[MediaImage::Y].mColInc = 1;
   13466             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
   13467             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
   13468             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
   13469             //Plane 1 (U)
   13470             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
   13471             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
   13472             img->mPlane[MediaImage::U].mRowInc =
   13473                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13474             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
   13475             img->mPlane[MediaImage::U].mVertSubsampling = 2;
   13476             //Plane 2 (V)
   13477             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
   13478             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
   13479             img->mPlane[MediaImage::V].mRowInc =
   13480                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13481             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
   13482             img->mPlane[MediaImage::V].mVertSubsampling = 2;
   13483             break;
   13484         }
   13485 
   13486         case OMX_COLOR_FormatYUV420Planar:
   13487         case OMX_COLOR_FormatYUV420SemiPlanar:
   13488             // We need not describe the standard OMX linear formats as these are
   13489             // understood by client. Fail this deliberately to let client fill-in
   13490             return OMX_ErrorUnsupportedSetting;
   13491 
   13492         default:
   13493             // Rest all formats which are non-linear cannot be described
   13494             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
   13495             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   13496             return OMX_ErrorNone;
   13497     };
   13498 
   13499     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
   13500     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
   13501     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
   13502     for (size_t i = 0; i < img->mNumPlanes; ++i) {
   13503         DEBUG_PRINT_LOW("  Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
   13504                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
   13505     }
   13506     return OMX_ErrorNone;
   13507 #endif //FLEXYUV_SUPPORTED
   13508 }
   13509 
   13510 void omx_vdec::prefetchNewBuffers() {
   13511 
   13512     struct v4l2_decoder_cmd dec;
   13513     uint32_t prefetch_count;
   13514     uint32_t prefetch_size;
   13515     uint32_t want_size;
   13516     uint32_t have_size;
   13517     int color_fmt, rc;
   13518     uint32_t new_calculated_size;
   13519     uint32_t new_buffer_size;
   13520     uint32_t new_buffer_count;
   13521     uint32_t old_buffer_size;
   13522     uint32_t old_buffer_count;
   13523 
   13524     memset((void *)&dec, 0 , sizeof(dec));
   13525     DEBUG_PRINT_LOW("Old size : %zu, count : %d, width : %u, height : %u\n",
   13526             drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount,
   13527             drv_ctx.video_resolution.frame_width,
   13528             drv_ctx.video_resolution.frame_height);
   13529     dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT;
   13530     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   13531         DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno);
   13532     } else {
   13533         DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n",
   13534                 dec.raw.data[0], dec.raw.data[1]);
   13535     }
   13536 
   13537     switch ((int)drv_ctx.output_format) {
   13538     case VDEC_YUV_FORMAT_NV12:
   13539         color_fmt = COLOR_FMT_NV12;
   13540         break;
   13541     case VDEC_YUV_FORMAT_NV12_UBWC:
   13542         color_fmt = COLOR_FMT_NV12_UBWC;
   13543         break;
   13544     case VDEC_YUV_FORMAT_NV12_TP10_UBWC:
   13545         color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
   13546         break;
   13547     default:
   13548         color_fmt = -1;
   13549         DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format);
   13550         return;
   13551     }
   13552 
   13553     new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height);
   13554     DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n",
   13555             m_reconfig_width, m_reconfig_height, new_calculated_size);
   13556     new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size;
   13557     new_buffer_count = dec.raw.data[1];
   13558     old_buffer_size = drv_ctx.op_buf.buffer_size;
   13559     old_buffer_count = drv_ctx.op_buf.actualcount;
   13560 
   13561     new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count;
   13562 
   13563     prefetch_count = new_buffer_count;
   13564     prefetch_size = new_buffer_size - old_buffer_size;
   13565     want_size = new_buffer_size * new_buffer_count;
   13566     have_size = old_buffer_size * old_buffer_count;
   13567 
   13568     if (want_size > have_size) {
   13569         DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size);
   13570         DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size);
   13571 
   13572         int ion_fd = open(MEM_DEVICE, O_RDONLY);
   13573         if (ion_fd < 0) {
   13574             DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd);
   13575             return;
   13576         }
   13577 
   13578         struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data));
   13579         struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data));
   13580         struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions));
   13581         size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count);
   13582 
   13583         if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) {
   13584             DEBUG_PRINT_ERROR("prefetch data allocation failed");
   13585             goto prefetch_exit;
   13586         }
   13587 
   13588         for (uint32_t i = 0; i < prefetch_count; i++) {
   13589             sizes[i] = prefetch_size;
   13590         }
   13591 
   13592         regions[0].nr_sizes = prefetch_count;
   13593         regions[0].sizes = sizes;
   13594         regions[0].vmid = ION_FLAG_CP_PIXEL;
   13595 
   13596         prefetch_data->nr_regions = 1;
   13597         prefetch_data->regions = regions;
   13598         prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
   13599 
   13600         custom_data->cmd = ION_IOC_PREFETCH;
   13601         custom_data->arg = (unsigned long )prefetch_data;
   13602 
   13603         rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data);
   13604         if (rc) {
   13605             DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno);
   13606         }
   13607 
   13608 prefetch_exit:
   13609         close(ion_fd);
   13610         free(sizes);
   13611         free(regions);
   13612         free(prefetch_data);
   13613         free(custom_data);
   13614     }
   13615 }
   13616 
   13617 
   13618 // No code beyond this !
   13619 
   13620 // inline import of vendor-extensions implementation
   13621 #include "omx_vdec_extensions.hpp"
   13622