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         dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10;
   1045     bool dither_enable = true;
   1046 
   1047     switch (m_dither_config) {
   1048     case DITHER_DISABLE:
   1049         dither_enable = false;
   1050         break;
   1051     case DITHER_COLORSPACE_EXCEPTBT2020:
   1052         dither_enable = (m_color_space == EXCEPT_BT2020);
   1053         break;
   1054     case DITHER_ALL_COLORSPACE:
   1055         dither_enable = true;
   1056         break;
   1057     default:
   1058         DEBUG_PRINT_ERROR("Unsupported dither configuration:%d", m_dither_config);
   1059     }
   1060 
   1061     if (tp10_enable && !dither_enable) {
   1062         drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_TP10_UBWC;
   1063         capture_capability = V4L2_PIX_FMT_NV12_TP10_UBWC;
   1064         cpu_access = false;
   1065 
   1066         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1067         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1068         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1069         if (rc) {
   1070             DEBUG_PRINT_ERROR("%s: Failed get format on capture mplane", __func__);
   1071             return OMX_ErrorUnsupportedSetting;
   1072         }
   1073         fmt.fmt.pix_mp.pixelformat = capture_capability;
   1074         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1075         if (rc) {
   1076             DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1077             return OMX_ErrorUnsupportedSetting;
   1078         }
   1079     }
   1080 
   1081 
   1082     if (!BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_IDLE_PENDING) &&
   1083         !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   1084         DEBUG_PRINT_LOW("Invalid state to decide on dpb-opb split");
   1085         return eRet;
   1086     }
   1087 
   1088 
   1089     if (cpu_access) {
   1090         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1091             /* Disabled split mode for VP9. In split mode the DPB buffers are part of the internal
   1092              * scratch buffers and the driver does not does the reference buffer management for
   1093              * scratch buffers. In case of VP9 with spatial scalability, when a sequence changed
   1094              * event is received with the new resolution, and when a flush is sent by the driver, it
   1095              * releases all the references of internal scratch buffers. However as per the VP9
   1096              * spatial scalability, even after the flush, the buffers which have not yet received
   1097              * release reference event should not be unmapped and freed. Currently in driver,
   1098              * reference buffer management of the internal scratch buffer is not implemented
   1099              * and hence the DPB buffers get unmapped. For other codecs it does not matter
   1100              * as with the new SPS/PPS, the DPB is flushed.
   1101              */
   1102             bool is_not_vp9 = eCompressionFormat != OMX_VIDEO_CodingVP9;
   1103             bool eligible_for_split_dpb_ubwc =
   1104                m_progressive == MSM_VIDC_PIC_STRUCT_PROGRESSIVE &&     //@ Due to Venus limitation for Interlaced, Split mode enabled only for Progressive.
   1105                is_not_vp9                                       &&     //@ Split mode disabled for VP9.
   1106                !drv_ctx.idr_only_decoding                       &&     //@ Split mode disabled for Thumbnail usecase.
   1107                !m_disable_split_mode;                                  //@ Set prop to disable split mode
   1108 
   1109             //Since opb is linear, dpb should also be linear.
   1110             if (split_opb_dpb_with_same_color_fmt) {
   1111                 eligible_for_split_dpb_ubwc = false;
   1112             }
   1113 
   1114             if (eligible_for_split_dpb_ubwc) {
   1115                 //split DPB-OPB
   1116                 //DPB -> UBWC , OPB -> Linear
   1117                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1118             } else if (split_opb_dpb_with_same_color_fmt) {
   1119                         //DPB -> Linear, OPB -> Linear
   1120                         eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1121             } else {
   1122                         //DPB-OPB combined linear
   1123                         eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1124            }
   1125         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1126             //split DPB-OPB
   1127             //DPB -> UBWC, OPB -> Linear
   1128             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1129         }
   1130     } else { //no cpu access
   1131         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1132             if (split_opb_dpb_with_same_color_fmt) {
   1133                 //split DPB-OPB
   1134                 //DPB -> UBWC, OPB -> UBWC
   1135                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1136             } else {
   1137                 //DPB-OPB combined UBWC
   1138                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1139             }
   1140         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1141             if (dither_enable) {
   1142                 //split DPB-OPB
   1143                 //DPB -> TP10UBWC, OPB -> UBWC
   1144                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1145             } else {
   1146                 //combined DPB-OPB
   1147                 //DPB -> TP10UBWC, OPB -> TP10UBWC
   1148                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1149             }
   1150         }
   1151     }
   1152     if (eRet) {
   1153         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
   1154     }
   1155 
   1156 
   1157 
   1158     return eRet;
   1159 }
   1160 
   1161 int omx_vdec::enable_downscalar()
   1162 {
   1163     int rc = 0;
   1164     struct v4l2_control control;
   1165     struct v4l2_format fmt;
   1166 
   1167     if (is_down_scalar_enabled) {
   1168         DEBUG_PRINT_LOW("%s: already enabled", __func__);
   1169         return 0;
   1170     }
   1171 
   1172     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
   1173     rc = decide_dpb_buffer_mode(true);
   1174     if (rc) {
   1175         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
   1176         return rc;
   1177     }
   1178     is_down_scalar_enabled = true;
   1179 
   1180     memset(&control, 0x0, sizeof(struct v4l2_control));
   1181     control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
   1182     control.value = 1;
   1183     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1184     if (rc) {
   1185         DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__);
   1186         return rc;
   1187     }
   1188 
   1189     return 0;
   1190 }
   1191 
   1192 int omx_vdec::disable_downscalar()
   1193 {
   1194     int rc = 0;
   1195     struct v4l2_control control;
   1196 
   1197     if (!is_down_scalar_enabled) {
   1198         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
   1199         return 0;
   1200     }
   1201 
   1202     rc = decide_dpb_buffer_mode(false);
   1203     if (rc < 0) {
   1204         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
   1205         return rc;
   1206     }
   1207     is_down_scalar_enabled = false;
   1208 
   1209     return rc;
   1210 }
   1211 
   1212 int omx_vdec::decide_downscalar()
   1213 {
   1214     int rc = 0;
   1215     struct v4l2_format fmt;
   1216     enum color_fmts color_format;
   1217     OMX_U32 width, height;
   1218     OMX_BOOL isPortraitVideo = OMX_FALSE;
   1219 
   1220     if (capture_capability == V4L2_PIX_FMT_NV12_TP10_UBWC) {
   1221         rc = disable_downscalar();
   1222         if (rc) {
   1223             DEBUG_PRINT_ERROR("Disable downscalar failed!");
   1224             return rc;
   1225         }
   1226         return 0;
   1227     }
   1228 
   1229     if  (!m_enable_downscalar) {
   1230         DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
   1231         return 0;
   1232     }
   1233 
   1234 #ifdef _QUERY_DISP_RES_
   1235     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1236     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1237     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1238     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1239     if (rc < 0) {
   1240        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1241        return rc;
   1242     }
   1243     isPortraitVideo = fmt.fmt.pix_mp.width < fmt.fmt.pix_mp.height ? OMX_TRUE : OMX_FALSE;
   1244     if (!m_downscalar_width || !m_downscalar_height) {
   1245         qdutils::DisplayAttributes dpa = {}, dsa = {}, dva = {};
   1246         int prim_config, ext_config, virt_config;
   1247 
   1248         prim_config = qdutils::getActiveConfig(qdutils::DISPLAY_PRIMARY);
   1249         dpa = qdutils::getDisplayAttributes(prim_config, qdutils::DISPLAY_PRIMARY);
   1250         DEBUG_PRINT_HIGH("%s: Primary dpa.xres = %d  dpa.yres=%d   dpa.xdpi = %f  dpa.ydpi = %f ",
   1251             __func__, dpa.xres, dpa.yres, dpa.xdpi, dpa.ydpi);
   1252 
   1253         ext_config = qdutils::getActiveConfig(qdutils::DISPLAY_EXTERNAL);
   1254         dsa = qdutils::getDisplayAttributes(ext_config, qdutils::DISPLAY_EXTERNAL);
   1255         DEBUG_PRINT_HIGH("%s: HDMI dsa.xres = %d  dsa.yres = %d   dsa.xdpi = %f  dsa.ydpi = %f ",
   1256             __func__, dsa.xres, dsa.yres, dsa.xdpi, dsa.ydpi);
   1257 
   1258         virt_config = qdutils::getActiveConfig(qdutils::DISPLAY_VIRTUAL);
   1259         dva = qdutils::getDisplayAttributes(virt_config, qdutils::DISPLAY_VIRTUAL);
   1260         DEBUG_PRINT_HIGH("%s: Virtual dva.xres = %d  dva.yres = %d   dva.xdpi = %f  dva.ydpi = %f ",
   1261             __func__, dva.xres, dva.yres, dva.xdpi, dva.ydpi);
   1262 
   1263         /* Below logic takes care of following conditions:
   1264          *   1. Choose display resolution as maximum resolution of all the connected
   1265          *      displays (secondary, primary, virtual), so that we do not downscale
   1266          *      unnecessarily which might be supported on one of the display losing quality.
   1267          *   2. Displays connected might be in landscape or portrait mode, so the xres might
   1268          *      be smaller or greater than the yres. So we first take the max of the two
   1269          *      in width and min of two in height and then rotate it if below point is true.
   1270          *   3. Video might also be in portrait mode, so invert the downscalar width and
   1271          *      height for such cases.
   1272          */
   1273         if (dsa.xres * dsa.yres > dpa.xres * dpa.yres) {
   1274             m_downscalar_width = MAX(dsa.xres, dsa.yres);
   1275             m_downscalar_height = MIN(dsa.xres, dsa.yres);
   1276         } else if (dva.xres * dva.yres > dpa.xres * dpa.yres) {
   1277             m_downscalar_width = MAX(dva.xres, dva.yres);
   1278             m_downscalar_height = MIN(dva.xres, dva.yres);
   1279 
   1280         } else {
   1281             m_downscalar_width = MAX(dpa.xres, dpa.yres);
   1282             m_downscalar_height = MIN(dpa.xres, dpa.yres);
   1283         }
   1284         if (isPortraitVideo) {
   1285             // Swap width and height
   1286             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
   1287             m_downscalar_height = m_downscalar_width ^ m_downscalar_height;
   1288             m_downscalar_width = m_downscalar_width ^ m_downscalar_height;
   1289         }
   1290     }
   1291     m_downscalar_width = ALIGN(m_downscalar_width, 128);
   1292     m_downscalar_height = ALIGN(m_downscalar_height, 32);
   1293 #endif
   1294 
   1295     if (!m_downscalar_width || !m_downscalar_height) {
   1296         DEBUG_PRINT_LOW("%s: Invalid downscalar configuration", __func__);
   1297         return 0;
   1298     }
   1299 
   1300     if (m_force_down_scalar) {
   1301         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
   1302         return 0;
   1303     }
   1304 
   1305     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1306     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1307     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1308     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1309     if (rc < 0) {
   1310        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1311        return rc;
   1312     }
   1313 
   1314     height = fmt.fmt.pix_mp.height;
   1315     width = fmt.fmt.pix_mp.width;
   1316 
   1317     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d m_is_display_session = %d", __func__,
   1318         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height, m_is_display_session);
   1319 
   1320     if ((fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) &&
   1321          m_is_display_session) {
   1322         rc = enable_downscalar();
   1323         if (rc < 0) {
   1324             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   1325             return rc;
   1326         }
   1327 
   1328         width = m_downscalar_width > fmt.fmt.pix_mp.width ?
   1329                             fmt.fmt.pix_mp.width : m_downscalar_width;
   1330         height = m_downscalar_height > fmt.fmt.pix_mp.height ?
   1331                             fmt.fmt.pix_mp.height : m_downscalar_height;
   1332         switch (capture_capability) {
   1333             case V4L2_PIX_FMT_NV12:
   1334                 color_format = COLOR_FMT_NV12;
   1335                 break;
   1336             case V4L2_PIX_FMT_NV12_UBWC:
   1337                 color_format = COLOR_FMT_NV12_UBWC;
   1338                 break;
   1339             case V4L2_PIX_FMT_NV12_TP10_UBWC:
   1340                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
   1341                 break;
   1342             default:
   1343                 DEBUG_PRINT_ERROR("Color format not recognized\n");
   1344                 rc = OMX_ErrorUndefined;
   1345                 return rc;
   1346         }
   1347     } else {
   1348 
   1349         rc = disable_downscalar();
   1350         if (rc < 0) {
   1351             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   1352             return rc;
   1353         }
   1354     }
   1355 
   1356     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1357     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1358     fmt.fmt.pix_mp.height = height;
   1359     fmt.fmt.pix_mp.width = width;
   1360     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1361     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1362     if (rc) {
   1363         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1364         return rc;
   1365     }
   1366 
   1367     rc = get_buffer_req(&drv_ctx.op_buf);
   1368     if (rc) {
   1369         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
   1370         return rc;
   1371     }
   1372 
   1373     return rc;
   1374 }
   1375 
   1376 /* ======================================================================
   1377    FUNCTION
   1378    omx_vdec::OMXCntrlProcessMsgCb
   1379 
   1380    DESCRIPTION
   1381    IL Client callbacks are generated through this routine. The decoder
   1382    provides the thread context for this routine.
   1383 
   1384    PARAMETERS
   1385    ctxt -- Context information related to the self.
   1386    id   -- Event identifier. This could be any of the following:
   1387    1. Command completion event
   1388    2. Buffer done callback event
   1389    3. Frame done callback event
   1390 
   1391    RETURN VALUE
   1392    None.
   1393 
   1394    ========================================================================== */
   1395 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
   1396 {
   1397     unsigned long p1; // Parameter - 1
   1398     unsigned long p2; // Parameter - 2
   1399     unsigned long ident;
   1400     unsigned qsize=0; // qsize
   1401     omx_vdec *pThis = (omx_vdec *) ctxt;
   1402 
   1403     if (!pThis) {
   1404         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
   1405                 __func__);
   1406         return;
   1407     }
   1408 
   1409     // Protect the shared queue data structure
   1410     do {
   1411         /*Read the message id's from the queue*/
   1412         pthread_mutex_lock(&pThis->m_lock);
   1413         qsize = pThis->m_cmd_q.m_size;
   1414         if (qsize) {
   1415             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
   1416         }
   1417 
   1418         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1419             qsize = pThis->m_ftb_q.m_size;
   1420             if (qsize) {
   1421                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
   1422             }
   1423         }
   1424 
   1425         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1426             qsize = pThis->m_etb_q.m_size;
   1427             if (qsize) {
   1428                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
   1429             }
   1430         }
   1431         pthread_mutex_unlock(&pThis->m_lock);
   1432 
   1433         /*process message if we have one*/
   1434         if (qsize > 0) {
   1435             id = ident;
   1436             switch (id) {
   1437                 case OMX_COMPONENT_GENERATE_EVENT:
   1438                     if (pThis->m_cb.EventHandler) {
   1439                         switch (p1) {
   1440                             case OMX_CommandStateSet:
   1441                                 pThis->m_state = (OMX_STATETYPE) p2;
   1442                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
   1443                                         pThis->m_state);
   1444                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1445                                         OMX_EventCmdComplete, p1, p2, NULL);
   1446                                 break;
   1447 
   1448                             case OMX_EventError:
   1449                                 if (p2 == OMX_StateInvalid) {
   1450                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
   1451                                     pThis->m_state = (OMX_STATETYPE) p2;
   1452                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1453                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
   1454                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
   1455                                     pThis->omx_report_error();
   1456                                 } else {
   1457                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1458                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
   1459                                 }
   1460                                 break;
   1461 
   1462                             case OMX_CommandPortDisable:
   1463                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
   1464                                 if (BITMASK_PRESENT(&pThis->m_flags,
   1465                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1466                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1467                                     break;
   1468                                 }
   1469                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
   1470                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1471                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   1472                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
   1473                                         DEBUG_PRINT_HIGH("Failed to release output buffers");
   1474                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
   1475                                     if (eRet !=  OMX_ErrorNone) {
   1476                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
   1477                                         pThis->omx_report_error();
   1478                                         break;
   1479                                     }
   1480                                 }
   1481                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1482                                         OMX_EventCmdComplete, p1, p2, NULL );
   1483                                 break;
   1484                             case OMX_CommandPortEnable:
   1485                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
   1486                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
   1487                                         OMX_EventCmdComplete, p1, p2, NULL );
   1488                                 pThis->in_reconfig = false;
   1489                                 break;
   1490 
   1491                             default:
   1492                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1493                                         OMX_EventCmdComplete, p1, p2, NULL );
   1494                                 break;
   1495 
   1496                         }
   1497                     } else {
   1498                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1499                     }
   1500                     break;
   1501                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
   1502                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   1503                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1504                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
   1505                         pThis->omx_report_error ();
   1506                     }
   1507                     break;
   1508                 case OMX_COMPONENT_GENERATE_ETB: {
   1509                         OMX_ERRORTYPE iret;
   1510                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
   1511                         if (iret == OMX_ErrorInsufficientResources) {
   1512                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
   1513                             pThis->omx_report_hw_overload ();
   1514                         } else if (iret != OMX_ErrorNone) {
   1515                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
   1516                             pThis->omx_report_error ();
   1517                         }
   1518                     }
   1519                     break;
   1520 
   1521                 case OMX_COMPONENT_GENERATE_FTB:
   1522                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
   1523                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1524                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
   1525                         pThis->omx_report_error ();
   1526                     }
   1527                     break;
   1528 
   1529                 case OMX_COMPONENT_GENERATE_COMMAND:
   1530                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
   1531                             (OMX_U32)p2,(OMX_PTR)NULL);
   1532                     break;
   1533 
   1534                 case OMX_COMPONENT_GENERATE_EBD:
   1535 
   1536                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
   1537                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
   1538                         pThis->omx_report_error ();
   1539                     } else {
   1540                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
   1541                             pThis->time_stamp_dts.remove_time_stamp(
   1542                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
   1543                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1544                                     ?true:false);
   1545                         }
   1546 
   1547                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1548                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
   1549                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
   1550                             pThis->omx_report_error ();
   1551                         }
   1552                     }
   1553                     break;
   1554                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
   1555                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
   1556                                             if (p1) {
   1557                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
   1558                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1559                                                         ?true:false);
   1560                                                 free(timestamp);
   1561                                             }
   1562                                         }
   1563                                         break;
   1564                 case OMX_COMPONENT_GENERATE_FBD:
   1565                                         if (p2 != VDEC_S_SUCCESS) {
   1566                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
   1567                                             pThis->omx_report_error ();
   1568                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1569                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
   1570                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
   1571                                             pThis->omx_report_error ();
   1572                                         }
   1573                                         break;
   1574 
   1575                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1576                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
   1577                                         if (!pThis->input_flush_progress) {
   1578                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1579                                         } else {
   1580                                             pThis->execute_input_flush();
   1581                                             if (pThis->m_cb.EventHandler) {
   1582                                                 if (p2 != VDEC_S_SUCCESS) {
   1583                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1584                                                     pThis->omx_report_error ();
   1585                                                 } else {
   1586                                                     /*Check if we need generate event for Flush done*/
   1587                                                     pThis->notify_flush_done(ctxt);
   1588 
   1589                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1590                                                                 OMX_COMPONENT_IDLE_PENDING)) {
   1591                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1592                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
   1593                                                             pThis->omx_report_error ();
   1594                                                         } else {
   1595                                                             pThis->streaming[OUTPUT_PORT] = false;
   1596                                                         }
   1597                                                         if (!pThis->output_flush_progress) {
   1598                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
   1599                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1600                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1601                                                         }
   1602                                                     }
   1603                                                 }
   1604                                             } else {
   1605                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1606                                             }
   1607                                         }
   1608                                         break;
   1609 
   1610                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1611                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
   1612                                         if (!pThis->output_flush_progress) {
   1613                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1614                                         } else {
   1615                                             pThis->execute_output_flush();
   1616                                             if (pThis->m_cb.EventHandler) {
   1617                                                 if (p2 != VDEC_S_SUCCESS) {
   1618                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1619                                                     pThis->omx_report_error ();
   1620                                                 } else {
   1621                                                     /*Check if we need generate event for Flush done*/
   1622                                                     pThis->notify_flush_done(ctxt);
   1623 
   1624                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1625                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1626                                                         DEBUG_PRINT_LOW("Internal flush complete");
   1627                                                         BITMASK_CLEAR (&pThis->m_flags,
   1628                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1629                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1630                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1631                                                             pThis->post_event(OMX_CommandPortDisable,
   1632                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1633                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1634                                                             BITMASK_CLEAR (&pThis->m_flags,
   1635                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1636                                                             BITMASK_CLEAR (&pThis->m_flags,
   1637                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1638 
   1639                                                         }
   1640                                                     }
   1641 
   1642                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1643                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1644                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
   1645                                                             pThis->omx_report_error ();
   1646                                                             break;
   1647                                                         }
   1648                                                         pThis->streaming[CAPTURE_PORT] = false;
   1649                                                         if (!pThis->input_flush_progress) {
   1650                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
   1651                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1652                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1653                                                         }
   1654                                                     }
   1655                                                 }
   1656                                             } else {
   1657                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1658                                             }
   1659                                         }
   1660                                         break;
   1661 
   1662                 case OMX_COMPONENT_GENERATE_START_DONE:
   1663                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1664 
   1665                                         if (pThis->m_cb.EventHandler) {
   1666                                             if (p2 != VDEC_S_SUCCESS) {
   1667                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
   1668                                                 pThis->omx_report_error ();
   1669                                             } else {
   1670                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
   1671                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1672                                                     DEBUG_PRINT_LOW("Move to executing");
   1673                                                     // Send the callback now
   1674                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1675                                                     pThis->m_state = OMX_StateExecuting;
   1676                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1677                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1678                                                             OMX_StateExecuting, NULL);
   1679                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1680                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1681                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1682                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1683                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
   1684                                                         pThis->omx_report_error ();
   1685                                                     }
   1686                                                 }
   1687                                             }
   1688                                         } else {
   1689                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
   1690                                         }
   1691                                         break;
   1692 
   1693                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1694                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1695                                         if (pThis->m_cb.EventHandler) {
   1696                                             if (p2 != VDEC_S_SUCCESS) {
   1697                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1698                                                 pThis->omx_report_error ();
   1699                                             } else {
   1700                                                 pThis->complete_pending_buffer_done_cbs();
   1701                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1702                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1703                                                     //Send the callback now
   1704                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1705                                                     pThis->m_state = OMX_StatePause;
   1706                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1707                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1708                                                             OMX_StatePause, NULL);
   1709                                                 }
   1710                                             }
   1711                                         } else {
   1712                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1713                                         }
   1714 
   1715                                         break;
   1716 
   1717                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1718                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1719                                         if (pThis->m_cb.EventHandler) {
   1720                                             if (p2 != VDEC_S_SUCCESS) {
   1721                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1722                                                 pThis->omx_report_error ();
   1723                                             } else {
   1724                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1725                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
   1726                                                     // Send the callback now
   1727                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1728                                                     pThis->m_state = OMX_StateExecuting;
   1729                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1730                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1731                                                             OMX_StateExecuting,NULL);
   1732                                                 }
   1733                                             }
   1734                                         } else {
   1735                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1736                                         }
   1737 
   1738                                         break;
   1739 
   1740                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1741                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1742                                         if (pThis->m_cb.EventHandler) {
   1743                                             if (p2 != VDEC_S_SUCCESS) {
   1744                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1745                                                 pThis->omx_report_error ();
   1746                                             } else {
   1747                                                 pThis->complete_pending_buffer_done_cbs();
   1748                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1749                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1750                                                     // Send the callback now
   1751                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1752                                                     pThis->m_state = OMX_StateIdle;
   1753                                                     DEBUG_PRINT_LOW("Move to Idle State");
   1754                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1755                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1756                                                             OMX_StateIdle,NULL);
   1757                                                 }
   1758                                             }
   1759                                         } else {
   1760                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1761                                         }
   1762 
   1763                                         break;
   1764 
   1765                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1766                                         if (p2 == OMX_IndexParamPortDefinition) {
   1767                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
   1768                                             pThis->in_reconfig = true;
   1769                                             pThis->m_need_turbo &= ~TURBO_MODE_HIGH_FPS;
   1770                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
   1771                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
   1772 
   1773                                             /* Check if resolution is changed in smooth streaming mode */
   1774                                             if (pThis->m_smoothstreaming_mode &&
   1775                                                 (pThis->framesize.nWidth !=
   1776                                                     pThis->drv_ctx.video_resolution.frame_width) ||
   1777                                                 (pThis->framesize.nHeight !=
   1778                                                     pThis->drv_ctx.video_resolution.frame_height)) {
   1779 
   1780                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
   1781                                                         pThis->framesize.nWidth,
   1782                                                         pThis->framesize.nHeight,
   1783                                                         pThis->drv_ctx.video_resolution.frame_width,
   1784                                                         pThis->drv_ctx.video_resolution.frame_height);
   1785 
   1786                                                 /* Update new resolution */
   1787                                                 pThis->framesize.nWidth =
   1788                                                        pThis->drv_ctx.video_resolution.frame_width;
   1789                                                 pThis->framesize.nHeight =
   1790                                                        pThis->drv_ctx.video_resolution.frame_height;
   1791 
   1792                                                 /* Update C2D with new resolution */
   1793                                                 if (!pThis->client_buffers.update_buffer_req()) {
   1794                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
   1795                                                 }
   1796                                             }
   1797 
   1798                                             /* Update new crop information */
   1799                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
   1800                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
   1801                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
   1802                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
   1803 
   1804                                             /* Validate the new crop information */
   1805                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
   1806                                                 pThis->drv_ctx.video_resolution.frame_width) {
   1807 
   1808                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
   1809                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
   1810                                                         pThis->drv_ctx.video_resolution.frame_width);
   1811                                                 pThis->rectangle.nLeft = 0;
   1812 
   1813                                                 if (pThis->rectangle.nWidth >
   1814                                                     pThis->drv_ctx.video_resolution.frame_width) {
   1815 
   1816                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
   1817                                                             pThis->rectangle.nWidth,
   1818                                                             pThis->drv_ctx.video_resolution.frame_width);
   1819                                                     pThis->rectangle.nWidth =
   1820                                                         pThis->drv_ctx.video_resolution.frame_width;
   1821                                                 }
   1822                                             }
   1823                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
   1824                                                 pThis->drv_ctx.video_resolution.frame_height) {
   1825 
   1826                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
   1827                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
   1828                                                     pThis->drv_ctx.video_resolution.frame_height);
   1829                                                 pThis->rectangle.nTop = 0;
   1830 
   1831                                                 if (pThis->rectangle.nHeight >
   1832                                                     pThis->drv_ctx.video_resolution.frame_height) {
   1833 
   1834                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
   1835                                                         pThis->rectangle.nHeight,
   1836                                                         pThis->drv_ctx.video_resolution.frame_height);
   1837                                                     pThis->rectangle.nHeight =
   1838                                                         pThis->drv_ctx.video_resolution.frame_height;
   1839                                                 }
   1840                                             }
   1841                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
   1842                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
   1843                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
   1844                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
   1845                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
   1846                                         } else if (p2 == OMX_QTIIndexConfigDescribeHDRColorInfo) {
   1847                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeHDRcolorinfo");
   1848                                         } else {
   1849                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
   1850                                             break;
   1851                                         }
   1852                                         if (pThis->m_debug.outfile) {
   1853                                             fclose(pThis->m_debug.outfile);
   1854                                             pThis->m_debug.outfile = NULL;
   1855                                         }
   1856                                         if (pThis->m_debug.out_ymeta_file) {
   1857                                             fclose(pThis->m_debug.out_ymeta_file);
   1858                                             pThis->m_debug.out_ymeta_file = NULL;
   1859                                         }
   1860                                         if (pThis->m_debug.out_uvmeta_file) {
   1861                                             fclose(pThis->m_debug.out_uvmeta_file);
   1862                                             pThis->m_debug.out_uvmeta_file = NULL;
   1863                                         }
   1864 
   1865                                         if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) {
   1866                                             pThis->prefetchNewBuffers();
   1867                                         }
   1868 
   1869                                         if (pThis->m_cb.EventHandler) {
   1870                                             uint32_t frame_data[7];
   1871                                             frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ?
   1872                                                 pThis->m_reconfig_height : pThis->rectangle.nHeight;
   1873                                             frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ?
   1874                                                 pThis->m_reconfig_width : pThis->rectangle.nWidth;
   1875 
   1876                                             frame_data[2] = (p2 == OMX_IndexParamPortDefinition) ?
   1877                                                 frame_data[0] : pThis->drv_ctx.video_resolution.frame_height;
   1878 
   1879                                             frame_data[3] = (p2 == OMX_IndexParamPortDefinition) ?
   1880                                                 frame_data[1] : pThis->drv_ctx.video_resolution.frame_width;
   1881                                             frame_data[4] = pThis->dpb_bit_depth;
   1882                                             frame_data[5] = pThis->m_color_space;
   1883                                             frame_data[6] = pThis->m_dither_config;
   1884 
   1885                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1886                                                     OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data );
   1887                                         } else {
   1888                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1889                                         }
   1890                                         break;
   1891 
   1892                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1893                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1894                                         if (pThis->m_cb.EventHandler) {
   1895                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1896                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1897                                         } else {
   1898                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1899                                         }
   1900                                         pThis->prev_ts = LLONG_MAX;
   1901                                         pThis->rst_prev_ts = true;
   1902                                         break;
   1903 
   1904                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1905                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1906                                         pThis->omx_report_error();
   1907                                         break;
   1908 
   1909                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1910                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
   1911                                         pThis->omx_report_unsupported_setting();
   1912                                         break;
   1913 
   1914                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
   1915                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
   1916                                         pThis->omx_report_hw_overload();
   1917                                         break;
   1918 
   1919                 default:
   1920                                         break;
   1921             }
   1922         }
   1923         pthread_mutex_lock(&pThis->m_lock);
   1924         qsize = pThis->m_cmd_q.m_size;
   1925         if (pThis->m_state != OMX_StatePause)
   1926             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1927         pthread_mutex_unlock(&pThis->m_lock);
   1928     } while (qsize>0);
   1929 
   1930 }
   1931 
   1932 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1933 {
   1934     int format_changed = 0;
   1935     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
   1936             (width != (int)drv_ctx.video_resolution.frame_width)) {
   1937         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
   1938                 width, drv_ctx.video_resolution.frame_width,
   1939                 height,drv_ctx.video_resolution.frame_height);
   1940         format_changed = 1;
   1941     }
   1942     drv_ctx.video_resolution.frame_height = height;
   1943     drv_ctx.video_resolution.frame_width = width;
   1944     drv_ctx.video_resolution.scan_lines = scan_lines;
   1945     drv_ctx.video_resolution.stride = stride;
   1946 
   1947     if (!is_down_scalar_enabled) {
   1948         rectangle.nLeft = m_extradata_info.output_crop_rect.nLeft;
   1949         rectangle.nTop = m_extradata_info.output_crop_rect.nTop;
   1950         rectangle.nWidth = m_extradata_info.output_crop_rect.nWidth;
   1951         rectangle.nHeight = m_extradata_info.output_crop_rect.nHeight;
   1952     }
   1953     return format_changed;
   1954 }
   1955 
   1956 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1957 {
   1958     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1959                 OMX_MAX_STRINGNAME_SIZE) &&
   1960             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1961         m_decoder_capability.max_width = 1280;
   1962         m_decoder_capability.max_height = 720;
   1963         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1964     }
   1965 
   1966     if ((drv_ctx.video_resolution.frame_width *
   1967                 drv_ctx.video_resolution.frame_height >
   1968                 m_decoder_capability.max_width *
   1969                 m_decoder_capability.max_height) ||
   1970             (drv_ctx.video_resolution.frame_width*
   1971              drv_ctx.video_resolution.frame_height <
   1972              m_decoder_capability.min_width *
   1973              m_decoder_capability.min_height)) {
   1974         DEBUG_PRINT_ERROR(
   1975                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1976                 drv_ctx.video_resolution.frame_width,
   1977                 drv_ctx.video_resolution.frame_height,
   1978                 m_decoder_capability.min_width,
   1979                 m_decoder_capability.min_height,
   1980                 m_decoder_capability.max_width,
   1981                 m_decoder_capability.max_height);
   1982         return OMX_ErrorUnsupportedSetting;
   1983     }
   1984     DEBUG_PRINT_HIGH("video session supported");
   1985     return OMX_ErrorNone;
   1986 }
   1987 
   1988 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
   1989 {
   1990     if (m_debug.in_buffer_log && !m_debug.infile) {
   1991         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   1992            snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v",
   1993                    m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1994         } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   1995                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc,
   1996                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1997         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   1998                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263",
   1999                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2000         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
   2001                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   2002                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
   2003                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2004         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   2005                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
   2006                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2007         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   2008                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   2009                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2010         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
   2011                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   2012                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2013         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   2014                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   2015                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2016         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2017                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   2018                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2019         } else {
   2020                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx",
   2021                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2022         }
   2023         m_debug.infile = fopen (m_debug.infile_name, "ab");
   2024         if (!m_debug.infile) {
   2025             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   2026             m_debug.infile_name[0] = '\0';
   2027             return -1;
   2028         }
   2029         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   2030                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2031             struct ivf_file_header {
   2032                 OMX_U8 signature[4]; //='DKIF';
   2033                 OMX_U8 version         ; //= 0;
   2034                 OMX_U8 headersize      ; //= 32;
   2035                 OMX_U32 FourCC;
   2036                 OMX_U8 width;
   2037                 OMX_U8 height;
   2038                 OMX_U32 rate;
   2039                 OMX_U32 scale;
   2040                 OMX_U32 length;
   2041                 OMX_U8 unused[4];
   2042             } file_header;
   2043 
   2044             memset((void *)&file_header,0,sizeof(file_header));
   2045             file_header.signature[0] = 'D';
   2046             file_header.signature[1] = 'K';
   2047             file_header.signature[2] = 'I';
   2048             file_header.signature[3] = 'F';
   2049             file_header.version = 0;
   2050             file_header.headersize = 32;
   2051             switch (drv_ctx.decoder_format) {
   2052                 case VDEC_CODECTYPE_VP8:
   2053                     file_header.FourCC = 0x30385056;
   2054                     break;
   2055                 case VDEC_CODECTYPE_VP9:
   2056                     file_header.FourCC = 0x30395056;
   2057                     break;
   2058                 default:
   2059                     DEBUG_PRINT_ERROR("unsupported format for VP8/VP9");
   2060                     break;
   2061             }
   2062             fwrite((const char *)&file_header,
   2063                     sizeof(file_header),1,m_debug.infile);
   2064          }
   2065     }
   2066     if (m_debug.infile && buffer_addr && buffer_len) {
   2067         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   2068                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   2069             struct vpx_ivf_frame_header {
   2070                 OMX_U32 framesize;
   2071                 OMX_U32 timestamp_lo;
   2072                 OMX_U32 timestamp_hi;
   2073             } vpx_frame_header;
   2074             vpx_frame_header.framesize = buffer_len;
   2075             /* Currently FW doesn't use timestamp values */
   2076             vpx_frame_header.timestamp_lo = 0;
   2077             vpx_frame_header.timestamp_hi = 0;
   2078             fwrite((const char *)&vpx_frame_header,
   2079                     sizeof(vpx_frame_header),1,m_debug.infile);
   2080         }
   2081         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
   2082     }
   2083     return 0;
   2084 }
   2085 
   2086 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
   2087     int buf_index = 0;
   2088     char *temp = NULL;
   2089 
   2090     if (!(m_debug.out_buffer_log || m_debug.out_meta_buffer_log) || !buffer || !buffer->nFilledLen)
   2091         return 0;
   2092 
   2093     if (m_debug.out_buffer_log && !m_debug.outfile) {
   2094         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv",
   2095                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2096         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
   2097         if (!m_debug.outfile) {
   2098             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
   2099             m_debug.outfile_name[0] = '\0';
   2100             return -1;
   2101         }
   2102     }
   2103 
   2104     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file) {
   2105         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
   2106                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2107         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
   2108                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   2109         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
   2110         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
   2111         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
   2112             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
   2113             m_debug.out_ymetafile_name[0] = '\0';
   2114             m_debug.out_uvmetafile_name[0] = '\0';
   2115             return -1;
   2116         }
   2117     }
   2118 
   2119     buf_index = buffer - m_out_mem_ptr;
   2120     temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   2121 
   2122     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC ||
   2123             drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   2124         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
   2125             drv_ctx.video_resolution.frame_width,
   2126             drv_ctx.video_resolution.frame_height);
   2127 
   2128         if (m_debug.outfile)
   2129             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
   2130 
   2131         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
   2132             unsigned int width = 0, height = 0;
   2133             unsigned int y_plane, y_meta_plane;
   2134             int y_stride = 0, y_sclines = 0;
   2135             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
   2136             int color_fmt = (drv_ctx.output_format== VDEC_YUV_FORMAT_NV12_UBWC)? COLOR_FMT_NV12_UBWC: COLOR_FMT_NV12_BPP10_UBWC;
   2137             int i;
   2138             int bytes_written = 0;
   2139 
   2140             width = drv_ctx.video_resolution.frame_width;
   2141             height = drv_ctx.video_resolution.frame_height;
   2142             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
   2143             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
   2144             y_stride = VENUS_Y_STRIDE(color_fmt, width);
   2145             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
   2146             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
   2147             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
   2148 
   2149             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
   2150             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
   2151 
   2152             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   2153             for (i = 0; i < y_meta_scanlines; i++) {
   2154                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
   2155                  temp += y_meta_stride;
   2156             }
   2157 
   2158             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
   2159             for(i = 0; i < uv_meta_scanlines; i++) {
   2160                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
   2161                 temp += uv_meta_stride;
   2162             }
   2163         }
   2164     } else if (m_debug.outfile && drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   2165         int stride = drv_ctx.video_resolution.stride;
   2166         int scanlines = drv_ctx.video_resolution.scan_lines;
   2167         if (m_smoothstreaming_mode) {
   2168             stride = drv_ctx.video_resolution.frame_width;
   2169             scanlines = drv_ctx.video_resolution.frame_height;
   2170             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
   2171             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
   2172         }
   2173         unsigned i;
   2174         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
   2175             drv_ctx.video_resolution.frame_width,
   2176             drv_ctx.video_resolution.frame_height, stride, scanlines);
   2177         int bytes_written = 0;
   2178         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   2179              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   2180              temp += stride;
   2181         }
   2182         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   2183         int stride_c = stride;
   2184         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   2185             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   2186             temp += stride_c;
   2187         }
   2188     }
   2189     return 0;
   2190 }
   2191 
   2192 /* ======================================================================
   2193    FUNCTION
   2194    omx_vdec::ComponentInit
   2195 
   2196    DESCRIPTION
   2197    Initialize the component.
   2198 
   2199    PARAMETERS
   2200    ctxt -- Context information related to the self.
   2201    id   -- Event identifier. This could be any of the following:
   2202    1. Command completion event
   2203    2. Buffer done callback event
   2204    3. Frame done callback event
   2205 
   2206    RETURN VALUE
   2207    None.
   2208 
   2209    ========================================================================== */
   2210 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   2211 {
   2212 
   2213     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2214     struct v4l2_fmtdesc fdesc;
   2215     struct v4l2_format fmt;
   2216     struct v4l2_requestbuffers bufreq;
   2217     struct v4l2_control control;
   2218     struct v4l2_frmsizeenum frmsize;
   2219     unsigned int   alignment = 0,buffer_size = 0;
   2220     int fds[2];
   2221     int r,ret=0;
   2222     bool codec_ambiguous = false;
   2223     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
   2224     char property_value[PROPERTY_VALUE_MAX] = {0};
   2225     FILE *soc_file = NULL;
   2226     char buffer[10];
   2227 
   2228 #ifdef _ANDROID_
   2229     char platform_name[PROPERTY_VALUE_MAX];
   2230     property_get("ro.board.platform", platform_name, "0");
   2231     if (!strncmp(platform_name, "msm8610", 7)) {
   2232         device_name = (OMX_STRING)"/dev/video/q6_dec";
   2233         is_q6_platform = true;
   2234         maxSmoothStreamingWidth = 1280;
   2235         maxSmoothStreamingHeight = 720;
   2236     }
   2237 #endif
   2238 
   2239     is_thulium_v1 = false;
   2240     soc_file = fopen("/sys/devices/soc0/soc_id", "r");
   2241     if (soc_file) {
   2242         fread(buffer, 1, 4, soc_file);
   2243         fclose(soc_file);
   2244         if (atoi(buffer) == 246) {
   2245             soc_file = fopen("/sys/devices/soc0/revision", "r");
   2246             if (soc_file) {
   2247                 fread(buffer, 1, 4, soc_file);
   2248                 fclose(soc_file);
   2249                 if (atoi(buffer) == 1) {
   2250                     is_thulium_v1 = true;
   2251                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
   2252                 }
   2253             }
   2254         }
   2255     }
   2256 
   2257 #ifdef _ANDROID_
   2258     /*
   2259      * turn off frame parsing for Android by default.
   2260      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
   2261      */
   2262     arbitrary_bytes = false;
   2263     property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   2264     if (atoi(property_value)) {
   2265         DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
   2266         arbitrary_bytes = true;
   2267     }
   2268 #endif
   2269 
   2270     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
   2271                 OMX_MAX_STRINGNAME_SIZE)) {
   2272         secure_mode = true;
   2273         arbitrary_bytes = false;
   2274         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   2275     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
   2276                 OMX_MAX_STRINGNAME_SIZE)) {
   2277         secure_mode = true;
   2278         arbitrary_bytes = false;
   2279         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
   2280     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
   2281                 OMX_MAX_STRINGNAME_SIZE)) {
   2282         secure_mode = true;
   2283         arbitrary_bytes = false;
   2284         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
   2285     } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
   2286                 OMX_MAX_STRINGNAME_SIZE)) {
   2287         secure_mode = true;
   2288         arbitrary_bytes = false;
   2289         role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
   2290     } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
   2291                 OMX_MAX_STRINGNAME_SIZE)) {
   2292         secure_mode = true;
   2293         arbitrary_bytes = false;
   2294         role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
   2295     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
   2296                 OMX_MAX_STRINGNAME_SIZE)) {
   2297         secure_mode = true;
   2298         arbitrary_bytes = false;
   2299         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
   2300     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
   2301                 OMX_MAX_STRINGNAME_SIZE)) {
   2302         secure_mode = true;
   2303         arbitrary_bytes = false;
   2304         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
   2305     }
   2306     else if (!strncmp(role, "OMX.qcom.video.decoder.vp8.secure",
   2307                 OMX_MAX_STRINGNAME_SIZE)) {
   2308         secure_mode = true;
   2309         arbitrary_bytes = false;
   2310         role = (OMX_STRING)"OMX.qcom.video.decoder.vp8";
   2311     }
   2312 
   2313     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   2314 
   2315     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
   2316 
   2317     if (drv_ctx.video_driver_fd < 0) {
   2318         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
   2319         return OMX_ErrorInsufficientResources;
   2320     }
   2321     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   2322     drv_ctx.frame_rate.fps_denominator = 1;
   2323     operating_frame_rate = DEFAULT_FPS;
   2324     m_poll_efd = eventfd(0, 0);
   2325     if (m_poll_efd < 0) {
   2326         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
   2327         return OMX_ErrorInsufficientResources;
   2328     }
   2329     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   2330     if (!ret) {
   2331         async_thread_created = true;
   2332         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   2333     }
   2334     if (ret) {
   2335         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
   2336         async_thread_created = false;
   2337         return OMX_ErrorInsufficientResources;
   2338     }
   2339 
   2340 #ifdef OUTPUT_EXTRADATA_LOG
   2341     outputExtradataFile = fopen (output_extradata_filename, "ab");
   2342 #endif
   2343 
   2344     // Copy the role information which provides the decoder kind
   2345     strlcpy(drv_ctx.kind,role,128);
   2346 
   2347     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   2348                 OMX_MAX_STRINGNAME_SIZE)) {
   2349         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   2350                 OMX_MAX_STRINGNAME_SIZE);
   2351         drv_ctx.timestamp_adjust = true;
   2352         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   2353         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   2354         output_capability=V4L2_PIX_FMT_MPEG4;
   2355         /*Initialize Start Code for MPEG4*/
   2356         codec_type_parse = CODEC_TYPE_MPEG4;
   2357         m_frame_parser.init_start_codes(codec_type_parse);
   2358     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   2359                 OMX_MAX_STRINGNAME_SIZE)) {
   2360         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   2361                 OMX_MAX_STRINGNAME_SIZE);
   2362         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   2363         output_capability = V4L2_PIX_FMT_MPEG2;
   2364         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   2365         /*Initialize Start Code for MPEG2*/
   2366         codec_type_parse = CODEC_TYPE_MPEG2;
   2367         m_frame_parser.init_start_codes(codec_type_parse);
   2368     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   2369                 OMX_MAX_STRINGNAME_SIZE)) {
   2370         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   2371         DEBUG_PRINT_LOW("H263 Decoder selected");
   2372         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   2373         eCompressionFormat = OMX_VIDEO_CodingH263;
   2374         output_capability = V4L2_PIX_FMT_H263;
   2375         codec_type_parse = CODEC_TYPE_H263;
   2376         m_frame_parser.init_start_codes(codec_type_parse);
   2377     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   2378                 OMX_MAX_STRINGNAME_SIZE)) {
   2379         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2380         DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
   2381         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   2382         output_capability = V4L2_PIX_FMT_DIVX_311;
   2383         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2384         codec_type_parse = CODEC_TYPE_DIVX;
   2385         m_frame_parser.init_start_codes(codec_type_parse);
   2386 
   2387     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   2388                 OMX_MAX_STRINGNAME_SIZE)) {
   2389         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2390         DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
   2391         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   2392         output_capability = V4L2_PIX_FMT_DIVX;
   2393         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2394         codec_type_parse = CODEC_TYPE_DIVX;
   2395         codec_ambiguous = true;
   2396         m_frame_parser.init_start_codes(codec_type_parse);
   2397 
   2398     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   2399                 OMX_MAX_STRINGNAME_SIZE)) {
   2400         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2401         DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
   2402         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   2403         output_capability = V4L2_PIX_FMT_DIVX;
   2404         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2405         codec_type_parse = CODEC_TYPE_DIVX;
   2406         codec_ambiguous = true;
   2407         m_frame_parser.init_start_codes(codec_type_parse);
   2408 
   2409     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   2410                 OMX_MAX_STRINGNAME_SIZE)) {
   2411         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   2412         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   2413         output_capability=V4L2_PIX_FMT_H264;
   2414         eCompressionFormat = OMX_VIDEO_CodingAVC;
   2415         codec_type_parse = CODEC_TYPE_H264;
   2416         m_frame_parser.init_start_codes(codec_type_parse);
   2417         m_frame_parser.init_nal_length(nal_length);
   2418         if (is_thulium_v1) {
   2419             arbitrary_bytes = true;
   2420             DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264");
   2421         }
   2422     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
   2423                 OMX_MAX_STRINGNAME_SIZE)) {
   2424         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   2425         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
   2426         output_capability = V4L2_PIX_FMT_H264_MVC;
   2427         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
   2428         codec_type_parse = CODEC_TYPE_H264;
   2429         m_frame_parser.init_start_codes(codec_type_parse);
   2430         m_frame_parser.init_nal_length(nal_length);
   2431     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
   2432                 OMX_MAX_STRINGNAME_SIZE)) {
   2433         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
   2434         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
   2435         output_capability = V4L2_PIX_FMT_HEVC;
   2436         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
   2437         codec_type_parse = CODEC_TYPE_HEVC;
   2438         m_frame_parser.init_start_codes(codec_type_parse);
   2439         m_frame_parser.init_nal_length(nal_length);
   2440     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   2441                 OMX_MAX_STRINGNAME_SIZE)) {
   2442         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2443         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   2444         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2445         codec_type_parse = CODEC_TYPE_VC1;
   2446         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   2447         m_frame_parser.init_start_codes(codec_type_parse);
   2448     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   2449                 OMX_MAX_STRINGNAME_SIZE)) {
   2450         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2451         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   2452         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2453         codec_type_parse = CODEC_TYPE_VC1;
   2454         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   2455         m_frame_parser.init_start_codes(codec_type_parse);
   2456     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   2457                 OMX_MAX_STRINGNAME_SIZE)) {
   2458         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   2459         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
   2460         output_capability = V4L2_PIX_FMT_VP8;
   2461         eCompressionFormat = OMX_VIDEO_CodingVP8;
   2462         codec_type_parse = CODEC_TYPE_VP8;
   2463         arbitrary_bytes = false;
   2464     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
   2465                 OMX_MAX_STRINGNAME_SIZE)) {
   2466         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   2467         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
   2468         output_capability = V4L2_PIX_FMT_VP9;
   2469         eCompressionFormat = OMX_VIDEO_CodingVP9;
   2470         codec_type_parse = CODEC_TYPE_VP9;
   2471         arbitrary_bytes = false;
   2472     } else {
   2473         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
   2474         eRet = OMX_ErrorInvalidComponentName;
   2475     }
   2476 
   2477     if (eRet == OMX_ErrorNone) {
   2478         OMX_COLOR_FORMATTYPE dest_color_format;
   2479         if (m_disable_ubwc_mode) {
   2480             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   2481         } else {
   2482             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   2483         }
   2484         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
   2485             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2486                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   2487         else
   2488             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2489                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2490         if (!client_buffers.set_color_format(dest_color_format)) {
   2491             DEBUG_PRINT_ERROR("Setting color format failed");
   2492             eRet = OMX_ErrorInsufficientResources;
   2493         }
   2494 
   2495         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
   2496         m_progressive = MSM_VIDC_PIC_STRUCT_PROGRESSIVE;
   2497 
   2498         if (m_disable_ubwc_mode) {
   2499             capture_capability = V4L2_PIX_FMT_NV12;
   2500         } else {
   2501             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   2502         }
   2503 
   2504         struct v4l2_capability cap;
   2505         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   2506         if (ret) {
   2507             DEBUG_PRINT_ERROR("Failed to query capabilities");
   2508             /*TODO: How to handle this case */
   2509         } else {
   2510             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   2511                 " version = %d, capabilities = %x", cap.driver, cap.card,
   2512                 cap.bus_info, cap.version, cap.capabilities);
   2513         }
   2514         ret=0;
   2515         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2516         fdesc.index=0;
   2517         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2518             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2519                     fdesc.pixelformat, fdesc.flags);
   2520             fdesc.index++;
   2521         }
   2522         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2523         fdesc.index=0;
   2524         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2525 
   2526             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2527                     fdesc.pixelformat, fdesc.flags);
   2528             fdesc.index++;
   2529         }
   2530         m_extradata_info.output_crop_rect.nLeft = 0;
   2531         m_extradata_info.output_crop_rect.nTop = 0;
   2532         m_extradata_info.output_crop_rect.nWidth = 320;
   2533         m_extradata_info.output_crop_rect.nHeight = 240;
   2534         update_resolution(320, 240, 320, 240);
   2535 
   2536         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2537         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2538         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2539         fmt.fmt.pix_mp.pixelformat = output_capability;
   2540         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2541         if (ret) {
   2542             /*TODO: How to handle this case */
   2543             DEBUG_PRINT_ERROR("Failed to set format on output port");
   2544             return OMX_ErrorInsufficientResources;
   2545         }
   2546         DEBUG_PRINT_HIGH("Set Format was successful");
   2547         if (codec_ambiguous) {
   2548             if (output_capability == V4L2_PIX_FMT_DIVX) {
   2549                 struct v4l2_control divx_ctrl;
   2550 
   2551                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   2552                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   2553                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   2554                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   2555                 } else {
   2556                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   2557                 }
   2558 
   2559                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   2560                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   2561                 if (ret) {
   2562                     DEBUG_PRINT_ERROR("Failed to set divx version");
   2563                 }
   2564             } else {
   2565                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   2566             }
   2567         }
   2568 
   2569         property_get("persist.vendor.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
   2570         m_conceal_color= atoi(property_value);
   2571         DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
   2572         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
   2573         control.value = m_conceal_color;
   2574         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2575         if (ret) {
   2576             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
   2577         }
   2578 
   2579         //Get the hardware capabilities
   2580         memset((void *)&frmsize,0,sizeof(frmsize));
   2581         frmsize.index = 0;
   2582         frmsize.pixel_format = output_capability;
   2583         ret = ioctl(drv_ctx.video_driver_fd,
   2584                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   2585         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   2586             DEBUG_PRINT_ERROR("Failed to get framesizes");
   2587             return OMX_ErrorHardware;
   2588         }
   2589 
   2590         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   2591             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   2592             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   2593             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   2594             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   2595         }
   2596 
   2597         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   2598         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2599         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2600         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2601         fmt.fmt.pix_mp.pixelformat = capture_capability;
   2602         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2603         if (ret) {
   2604             /*TODO: How to handle this case */
   2605             DEBUG_PRINT_ERROR("Failed to set format on capture port");
   2606         }
   2607         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
   2608         framesize.nWidth = drv_ctx.video_resolution.frame_width;
   2609         framesize.nHeight = drv_ctx.video_resolution.frame_height;
   2610 
   2611         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
   2612         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   2613         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   2614 
   2615         DEBUG_PRINT_HIGH("Set Format was successful");
   2616         if (secure_mode) {
   2617             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   2618             control.value = 1;
   2619             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
   2620             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   2621             if (ret) {
   2622                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
   2623                 return OMX_ErrorInsufficientResources;
   2624             }
   2625         }
   2626         if (output_capability == V4L2_PIX_FMT_H264_MVC) {
   2627             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
   2628             control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
   2629             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2630             if (ret) {
   2631                 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
   2632                 return OMX_ErrorInsufficientResources;
   2633             }
   2634         }
   2635 
   2636         if (is_thulium_v1) {
   2637             eRet = enable_smoothstreaming();
   2638             if (eRet != OMX_ErrorNone) {
   2639                DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver");
   2640                return eRet;
   2641             }
   2642         }
   2643 
   2644         /*Get the Buffer requirements for input and output ports*/
   2645         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2646         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2647 
   2648         if (secure_mode) {
   2649             drv_ctx.op_buf.alignment = SECURE_ALIGN;
   2650             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
   2651         } else {
   2652             drv_ctx.op_buf.alignment = SZ_4K;
   2653             drv_ctx.ip_buf.alignment = SZ_4K;
   2654         }
   2655 
   2656         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   2657         drv_ctx.extradata = 0;
   2658         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   2659         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   2660         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   2661         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2662         drv_ctx.idr_only_decoding = 0;
   2663 
   2664 #ifdef _ANDROID_
   2665         property_get("vendor.vidc.dec.enable.downscalar",property_value,"0");
   2666         if (atoi(property_value)) {
   2667             m_enable_downscalar =  atoi(property_value);
   2668             property_get("vendor.vidc.dec.downscalar_width",property_value,"0");
   2669             if (atoi(property_value)) {
   2670                 m_downscalar_width = atoi(property_value);
   2671             }
   2672             property_get("vendor.vidc.dec.downscalar_height",property_value,"0");
   2673             if (atoi(property_value)) {
   2674                 m_downscalar_height = atoi(property_value);
   2675             }
   2676 
   2677             if (m_downscalar_width < m_decoder_capability.min_width ||
   2678                 m_downscalar_height < m_decoder_capability.min_height) {
   2679                 m_downscalar_width = 0;
   2680                 m_downscalar_height = 0;
   2681             }
   2682 
   2683             DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n",
   2684                 m_downscalar_width, m_downscalar_height);
   2685         }
   2686         property_get("vendor.vidc.disable.split.mode",property_value,"0");
   2687         m_disable_split_mode = atoi(property_value);
   2688         DEBUG_PRINT_HIGH("split mode is %s", m_disable_split_mode ? "disabled" : "enabled");
   2689 #endif
   2690         m_state = OMX_StateLoaded;
   2691 #ifdef DEFAULT_EXTRADATA
   2692         enable_extradata(DEFAULT_EXTRADATA, true, true);
   2693 #endif
   2694         eRet = get_buffer_req(&drv_ctx.ip_buf);
   2695         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
   2696         get_buffer_req(&drv_ctx.op_buf);
   2697         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2698                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
   2699                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2700                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   2701                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   2702                     h264_scratch.nFilledLen = 0;
   2703                     h264_scratch.nOffset = 0;
   2704 
   2705                     if (h264_scratch.pBuffer == NULL) {
   2706                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
   2707                         return OMX_ErrorInsufficientResources;
   2708                     }
   2709         }
   2710         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2711             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2712             if (m_frame_parser.mutils == NULL) {
   2713                 m_frame_parser.mutils = new H264_Utils();
   2714                 if (m_frame_parser.mutils == NULL) {
   2715                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
   2716                     eRet = OMX_ErrorInsufficientResources;
   2717                 } else {
   2718                     m_frame_parser.mutils->initialize_frame_checking_environment();
   2719                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   2720                 }
   2721             }
   2722 
   2723             h264_parser = new h264_stream_parser();
   2724             if (!h264_parser) {
   2725                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   2726                 eRet = OMX_ErrorInsufficientResources;
   2727             }
   2728         }
   2729 
   2730         if (pipe(fds)) {
   2731             DEBUG_PRINT_ERROR("pipe creation failed");
   2732             eRet = OMX_ErrorInsufficientResources;
   2733         } else {
   2734             m_pipe_in = fds[0];
   2735             m_pipe_out = fds[1];
   2736             msg_thread_created = true;
   2737             r = pthread_create(&msg_thread_id,0,message_thread_dec,this);
   2738 
   2739             if (r < 0) {
   2740                 DEBUG_PRINT_ERROR("component_init(): message_thread_dec creation failed");
   2741                 msg_thread_created = false;
   2742                 eRet = OMX_ErrorInsufficientResources;
   2743             }
   2744         }
   2745     }
   2746 
   2747     {
   2748         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
   2749         init_vendor_extensions(*extStore);
   2750         mVendorExtensionStore.dumpExtensions((const char *)role);
   2751     }
   2752 
   2753     if (eRet != OMX_ErrorNone) {
   2754         DEBUG_PRINT_ERROR("Component Init Failed");
   2755     } else {
   2756         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
   2757                 drv_ctx.video_driver_fd);
   2758     }
   2759     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   2760     return eRet;
   2761 }
   2762 
   2763 /* ======================================================================
   2764    FUNCTION
   2765    omx_vdec::GetComponentVersion
   2766 
   2767    DESCRIPTION
   2768    Returns the component version.
   2769 
   2770    PARAMETERS
   2771    TBD.
   2772 
   2773    RETURN VALUE
   2774    OMX_ErrorNone.
   2775 
   2776    ========================================================================== */
   2777 OMX_ERRORTYPE  omx_vdec::get_component_version
   2778 (
   2779  OMX_IN OMX_HANDLETYPE hComp,
   2780  OMX_OUT OMX_STRING componentName,
   2781  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   2782  OMX_OUT OMX_VERSIONTYPE* specVersion,
   2783  OMX_OUT OMX_UUIDTYPE* componentUUID
   2784  )
   2785 {
   2786     (void) hComp;
   2787     (void) componentName;
   2788     (void) componentVersion;
   2789     (void) componentUUID;
   2790     if (m_state == OMX_StateInvalid) {
   2791         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
   2792         return OMX_ErrorInvalidState;
   2793     }
   2794     /* TBD -- Return the proper version */
   2795     if (specVersion) {
   2796         specVersion->nVersion = OMX_SPEC_VERSION;
   2797     }
   2798     return OMX_ErrorNone;
   2799 }
   2800 /* ======================================================================
   2801    FUNCTION
   2802    omx_vdec::SendCommand
   2803 
   2804    DESCRIPTION
   2805    Returns zero if all the buffers released..
   2806 
   2807    PARAMETERS
   2808    None.
   2809 
   2810    RETURN VALUE
   2811    true/false
   2812 
   2813    ========================================================================== */
   2814 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   2815         OMX_IN OMX_COMMANDTYPE cmd,
   2816         OMX_IN OMX_U32 param1,
   2817         OMX_IN OMX_PTR cmdData
   2818         )
   2819 {
   2820     (void) hComp;
   2821     (void) cmdData;
   2822     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
   2823     if (m_state == OMX_StateInvalid) {
   2824         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
   2825         return OMX_ErrorInvalidState;
   2826     }
   2827     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   2828             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   2829         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
   2830                 "to invalid port: %u", (unsigned int)param1);
   2831         return OMX_ErrorBadPortIndex;
   2832     }
   2833 
   2834     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   2835     sem_wait(&m_cmd_lock);
   2836     DEBUG_PRINT_LOW("send_command: Command Processed");
   2837     return OMX_ErrorNone;
   2838 }
   2839 
   2840 /* ======================================================================
   2841    FUNCTION
   2842    omx_vdec::SendCommand
   2843 
   2844    DESCRIPTION
   2845    Returns zero if all the buffers released..
   2846 
   2847    PARAMETERS
   2848    None.
   2849 
   2850    RETURN VALUE
   2851    true/false
   2852 
   2853    ========================================================================== */
   2854 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   2855         OMX_IN OMX_COMMANDTYPE cmd,
   2856         OMX_IN OMX_U32 param1,
   2857         OMX_IN OMX_PTR cmdData
   2858         )
   2859 {
   2860     (void) hComp;
   2861     (void) cmdData;
   2862     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2863     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   2864     int bFlag = 1,sem_posted = 0,ret=0;
   2865 
   2866     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
   2867     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
   2868             m_state, eState);
   2869 
   2870     if (cmd == OMX_CommandStateSet) {
   2871         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   2872         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   2873         /***************************/
   2874         /* Current State is Loaded */
   2875         /***************************/
   2876         if (m_state == OMX_StateLoaded) {
   2877             if (eState == OMX_StateIdle) {
   2878                 //if all buffers are allocated or all ports disabled
   2879                 if (allocate_done() ||
   2880                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   2881                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
   2882                 } else {
   2883                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
   2884                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   2885                     // Skip the event notification
   2886                     bFlag = 0;
   2887                 }
   2888             }
   2889             /* Requesting transition from Loaded to Loaded */
   2890             else if (eState == OMX_StateLoaded) {
   2891                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
   2892                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2893                         OMX_COMPONENT_GENERATE_EVENT);
   2894                 eRet = OMX_ErrorSameState;
   2895             }
   2896             /* Requesting transition from Loaded to WaitForResources */
   2897             else if (eState == OMX_StateWaitForResources) {
   2898                 /* Since error is None , we will post an event
   2899                    at the end of this function definition */
   2900                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
   2901             }
   2902             /* Requesting transition from Loaded to Executing */
   2903             else if (eState == OMX_StateExecuting) {
   2904                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
   2905                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2906                         OMX_COMPONENT_GENERATE_EVENT);
   2907                 eRet = OMX_ErrorIncorrectStateTransition;
   2908             }
   2909             /* Requesting transition from Loaded to Pause */
   2910             else if (eState == OMX_StatePause) {
   2911                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
   2912                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2913                         OMX_COMPONENT_GENERATE_EVENT);
   2914                 eRet = OMX_ErrorIncorrectStateTransition;
   2915             }
   2916             /* Requesting transition from Loaded to Invalid */
   2917             else if (eState == OMX_StateInvalid) {
   2918                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
   2919                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2920                 eRet = OMX_ErrorInvalidState;
   2921             } else {
   2922                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
   2923                         eState);
   2924                 eRet = OMX_ErrorBadParameter;
   2925             }
   2926         }
   2927 
   2928         /***************************/
   2929         /* Current State is IDLE */
   2930         /***************************/
   2931         else if (m_state == OMX_StateIdle) {
   2932             if (eState == OMX_StateLoaded) {
   2933                 if (release_done()) {
   2934                     /*
   2935                      * Since error is None , we will post an event at the end
   2936                      * of this function definition
   2937                      * Reset buffer requirements here to ensure setting buffer requirement
   2938                      * when component move to executing state from loaded state via Idle.
   2939                      */
   2940                     drv_ctx.op_buf.buffer_size = 0;
   2941                     drv_ctx.op_buf.actualcount = 0;
   2942                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
   2943                 } else {
   2944                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
   2945                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   2946                     // Skip the event notification
   2947                     bFlag = 0;
   2948                 }
   2949             }
   2950             /* Requesting transition from Idle to Executing */
   2951             else if (eState == OMX_StateExecuting) {
   2952                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2953                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   2954                 bFlag = 1;
   2955                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2956                 m_state=OMX_StateExecuting;
   2957                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
   2958             }
   2959             /* Requesting transition from Idle to Idle */
   2960             else if (eState == OMX_StateIdle) {
   2961                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
   2962                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2963                         OMX_COMPONENT_GENERATE_EVENT);
   2964                 eRet = OMX_ErrorSameState;
   2965             }
   2966             /* Requesting transition from Idle to WaitForResources */
   2967             else if (eState == OMX_StateWaitForResources) {
   2968                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
   2969                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2970                         OMX_COMPONENT_GENERATE_EVENT);
   2971                 eRet = OMX_ErrorIncorrectStateTransition;
   2972             }
   2973             /* Requesting transition from Idle to Pause */
   2974             else if (eState == OMX_StatePause) {
   2975                 /*To pause the Video core we need to start the driver*/
   2976                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   2977                       NULL) < */0) {
   2978                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
   2979                     omx_report_error ();
   2980                     eRet = OMX_ErrorHardware;
   2981                 } else {
   2982                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   2983                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
   2984                     bFlag = 0;
   2985                 }
   2986             }
   2987             /* Requesting transition from Idle to Invalid */
   2988             else if (eState == OMX_StateInvalid) {
   2989                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
   2990                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2991                 eRet = OMX_ErrorInvalidState;
   2992             } else {
   2993                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
   2994                 eRet = OMX_ErrorBadParameter;
   2995             }
   2996         }
   2997 
   2998         /******************************/
   2999         /* Current State is Executing */
   3000         /******************************/
   3001         else if (m_state == OMX_StateExecuting) {
   3002             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
   3003             /* Requesting transition from Executing to Idle */
   3004             if (eState == OMX_StateIdle) {
   3005                 /* Since error is None , we will post an event
   3006                    at the end of this function definition
   3007                  */
   3008                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
   3009                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   3010                 if (!sem_posted) {
   3011                     sem_posted = 1;
   3012                     sem_post (&m_cmd_lock);
   3013                     execute_omx_flush(OMX_ALL);
   3014                 }
   3015                 bFlag = 0;
   3016             }
   3017             /* Requesting transition from Executing to Paused */
   3018             else if (eState == OMX_StatePause) {
   3019                 DEBUG_PRINT_LOW("PAUSE Command Issued");
   3020                 m_state = OMX_StatePause;
   3021                 bFlag = 1;
   3022             }
   3023             /* Requesting transition from Executing to Loaded */
   3024             else if (eState == OMX_StateLoaded) {
   3025                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
   3026                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3027                         OMX_COMPONENT_GENERATE_EVENT);
   3028                 eRet = OMX_ErrorIncorrectStateTransition;
   3029             }
   3030             /* Requesting transition from Executing to WaitForResources */
   3031             else if (eState == OMX_StateWaitForResources) {
   3032                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
   3033                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3034                         OMX_COMPONENT_GENERATE_EVENT);
   3035                 eRet = OMX_ErrorIncorrectStateTransition;
   3036             }
   3037             /* Requesting transition from Executing to Executing */
   3038             else if (eState == OMX_StateExecuting) {
   3039                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
   3040                 post_event(OMX_EventError,OMX_ErrorSameState,\
   3041                         OMX_COMPONENT_GENERATE_EVENT);
   3042                 eRet = OMX_ErrorSameState;
   3043             }
   3044             /* Requesting transition from Executing to Invalid */
   3045             else if (eState == OMX_StateInvalid) {
   3046                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
   3047                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3048                 eRet = OMX_ErrorInvalidState;
   3049             } else {
   3050                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
   3051                 eRet = OMX_ErrorBadParameter;
   3052             }
   3053         }
   3054         /***************************/
   3055         /* Current State is Pause  */
   3056         /***************************/
   3057         else if (m_state == OMX_StatePause) {
   3058             /* Requesting transition from Pause to Executing */
   3059             if (eState == OMX_StateExecuting) {
   3060                 DEBUG_PRINT_LOW("Pause --> Executing");
   3061                 m_state = OMX_StateExecuting;
   3062                 bFlag = 1;
   3063             }
   3064             /* Requesting transition from Pause to Idle */
   3065             else if (eState == OMX_StateIdle) {
   3066                 /* Since error is None , we will post an event
   3067                    at the end of this function definition */
   3068                 DEBUG_PRINT_LOW("Pause --> Idle");
   3069                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   3070                 if (!sem_posted) {
   3071                     sem_posted = 1;
   3072                     sem_post (&m_cmd_lock);
   3073                     execute_omx_flush(OMX_ALL);
   3074                 }
   3075                 bFlag = 0;
   3076             }
   3077             /* Requesting transition from Pause to loaded */
   3078             else if (eState == OMX_StateLoaded) {
   3079                 DEBUG_PRINT_ERROR("Pause --> loaded");
   3080                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3081                         OMX_COMPONENT_GENERATE_EVENT);
   3082                 eRet = OMX_ErrorIncorrectStateTransition;
   3083             }
   3084             /* Requesting transition from Pause to WaitForResources */
   3085             else if (eState == OMX_StateWaitForResources) {
   3086                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
   3087                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3088                         OMX_COMPONENT_GENERATE_EVENT);
   3089                 eRet = OMX_ErrorIncorrectStateTransition;
   3090             }
   3091             /* Requesting transition from Pause to Pause */
   3092             else if (eState == OMX_StatePause) {
   3093                 DEBUG_PRINT_ERROR("Pause --> Pause");
   3094                 post_event(OMX_EventError,OMX_ErrorSameState,\
   3095                         OMX_COMPONENT_GENERATE_EVENT);
   3096                 eRet = OMX_ErrorSameState;
   3097             }
   3098             /* Requesting transition from Pause to Invalid */
   3099             else if (eState == OMX_StateInvalid) {
   3100                 DEBUG_PRINT_ERROR("Pause --> Invalid");
   3101                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3102                 eRet = OMX_ErrorInvalidState;
   3103             } else {
   3104                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
   3105                 eRet = OMX_ErrorBadParameter;
   3106             }
   3107         }
   3108         /***************************/
   3109         /* Current State is WaitForResources  */
   3110         /***************************/
   3111         else if (m_state == OMX_StateWaitForResources) {
   3112             /* Requesting transition from WaitForResources to Loaded */
   3113             if (eState == OMX_StateLoaded) {
   3114                 /* Since error is None , we will post an event
   3115                    at the end of this function definition */
   3116                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
   3117             }
   3118             /* Requesting transition from WaitForResources to WaitForResources */
   3119             else if (eState == OMX_StateWaitForResources) {
   3120                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
   3121                 post_event(OMX_EventError,OMX_ErrorSameState,
   3122                         OMX_COMPONENT_GENERATE_EVENT);
   3123                 eRet = OMX_ErrorSameState;
   3124             }
   3125             /* Requesting transition from WaitForResources to Executing */
   3126             else if (eState == OMX_StateExecuting) {
   3127                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
   3128                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3129                         OMX_COMPONENT_GENERATE_EVENT);
   3130                 eRet = OMX_ErrorIncorrectStateTransition;
   3131             }
   3132             /* Requesting transition from WaitForResources to Pause */
   3133             else if (eState == OMX_StatePause) {
   3134                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
   3135                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   3136                         OMX_COMPONENT_GENERATE_EVENT);
   3137                 eRet = OMX_ErrorIncorrectStateTransition;
   3138             }
   3139             /* Requesting transition from WaitForResources to Invalid */
   3140             else if (eState == OMX_StateInvalid) {
   3141                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
   3142                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   3143                 eRet = OMX_ErrorInvalidState;
   3144             }
   3145             /* Requesting transition from WaitForResources to Loaded -
   3146                is NOT tested by Khronos TS */
   3147 
   3148         } else {
   3149             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
   3150             eRet = OMX_ErrorBadParameter;
   3151         }
   3152     }
   3153     /********************************/
   3154     /* Current State is Invalid */
   3155     /*******************************/
   3156     else if (m_state == OMX_StateInvalid) {
   3157         /* State Transition from Inavlid to any state */
   3158         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   3159                     || OMX_StateIdle || OMX_StateExecuting
   3160                     || OMX_StatePause || OMX_StateInvalid)) {
   3161             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
   3162             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   3163                     OMX_COMPONENT_GENERATE_EVENT);
   3164             eRet = OMX_ErrorInvalidState;
   3165         }
   3166     } else if (cmd == OMX_CommandFlush) {
   3167         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
   3168                 "with param1: %u", (unsigned int)param1);
   3169 #ifdef _MSM8974_
   3170         send_codec_config();
   3171 #endif
   3172         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
   3173                     param1 == OMX_ALL)) {
   3174             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
   3175                struct timespec ts;
   3176 
   3177                clock_gettime(CLOCK_REALTIME, &ts);
   3178                ts.tv_sec += 2;
   3179                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
   3180                        m_queued_codec_config_count);
   3181                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
   3182                if (sem_timedwait(&m_safe_flush, &ts)) {
   3183                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
   3184                }
   3185                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
   3186             }
   3187         }
   3188 
   3189         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   3190             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   3191         }
   3192         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   3193             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   3194         }
   3195         if (!sem_posted) {
   3196             sem_posted = 1;
   3197             DEBUG_PRINT_LOW("Set the Semaphore");
   3198             sem_post (&m_cmd_lock);
   3199             execute_omx_flush(param1);
   3200         }
   3201         bFlag = 0;
   3202     } else if ( cmd == OMX_CommandPortEnable) {
   3203         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
   3204                 "with param1: %u", (unsigned int)param1);
   3205         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3206             m_inp_bEnabled = OMX_TRUE;
   3207 
   3208             if ( (m_state == OMX_StateLoaded &&
   3209                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3210                     || allocate_input_done()) {
   3211                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   3212                         OMX_COMPONENT_GENERATE_EVENT);
   3213             } else {
   3214                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3215                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   3216                 // Skip the event notification
   3217                 bFlag = 0;
   3218             }
   3219         }
   3220         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3221             DEBUG_PRINT_LOW("Enable output Port command recieved");
   3222             m_out_bEnabled = OMX_TRUE;
   3223 
   3224             if ( (m_state == OMX_StateLoaded &&
   3225                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3226                     || (allocate_output_done())) {
   3227                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   3228                         OMX_COMPONENT_GENERATE_EVENT);
   3229 
   3230             } else {
   3231                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3232                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3233                 // Skip the event notification
   3234                 bFlag = 0;
   3235                 /* enable/disable downscaling if required */
   3236                 ret = decide_downscalar();
   3237                 if (ret) {
   3238                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
   3239                 }
   3240             }
   3241         }
   3242     } else if (cmd == OMX_CommandPortDisable) {
   3243         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
   3244                 "with param1: %u", (unsigned int)param1);
   3245         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3246             codec_config_flag = false;
   3247             m_inp_bEnabled = OMX_FALSE;
   3248             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3249                     && release_input_done()) {
   3250                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   3251                         OMX_COMPONENT_GENERATE_EVENT);
   3252             } else {
   3253                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3254                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3255                     if (!sem_posted) {
   3256                         sem_posted = 1;
   3257                         sem_post (&m_cmd_lock);
   3258                     }
   3259                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   3260                 }
   3261 
   3262                 // Skip the event notification
   3263                 bFlag = 0;
   3264             }
   3265         }
   3266         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3267             m_out_bEnabled = OMX_FALSE;
   3268             DEBUG_PRINT_LOW("Disable output Port command recieved");
   3269             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3270                     && release_output_done()) {
   3271                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   3272                         OMX_COMPONENT_GENERATE_EVENT);
   3273             } else {
   3274                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3275                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3276                     if (!sem_posted) {
   3277                         sem_posted = 1;
   3278                         sem_post (&m_cmd_lock);
   3279                     }
   3280                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   3281                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   3282                 }
   3283                 // Skip the event notification
   3284                 bFlag = 0;
   3285 
   3286             }
   3287         }
   3288     } else {
   3289         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
   3290         eRet = OMX_ErrorNotImplemented;
   3291     }
   3292     if (eRet == OMX_ErrorNone && bFlag) {
   3293         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   3294     }
   3295     if (!sem_posted) {
   3296         sem_post(&m_cmd_lock);
   3297     }
   3298 
   3299     return eRet;
   3300 }
   3301 
   3302 /* ======================================================================
   3303    FUNCTION
   3304    omx_vdec::ExecuteOmxFlush
   3305 
   3306    DESCRIPTION
   3307    Executes the OMX flush.
   3308 
   3309    PARAMETERS
   3310    flushtype - input flush(1)/output flush(0)/ both.
   3311 
   3312    RETURN VALUE
   3313    true/false
   3314 
   3315    ========================================================================== */
   3316 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   3317 {
   3318     bool bRet = false;
   3319     struct v4l2_plane plane;
   3320     struct v4l2_buffer v4l2_buf;
   3321     struct v4l2_decoder_cmd dec;
   3322     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
   3323     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   3324     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   3325 
   3326     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   3327 
   3328     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   3329         output_flush_progress = true;
   3330         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3331     } else {
   3332         /* XXX: The driver/hardware does not support flushing of individual ports
   3333          * in all states. So we pretty much need to flush both ports internally,
   3334          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   3335          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   3336          * we automatically omit sending the FLUSH done for the "opposite" port. */
   3337         input_flush_progress = true;
   3338         output_flush_progress = true;
   3339         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3340         request_perf_level(VIDC_TURBO);
   3341     }
   3342 
   3343     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   3344         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
   3345         bRet = false;
   3346     }
   3347 
   3348     return bRet;
   3349 }
   3350 /*=========================================================================
   3351 FUNCTION : execute_output_flush
   3352 
   3353 DESCRIPTION
   3354 Executes the OMX flush at OUTPUT PORT.
   3355 
   3356 PARAMETERS
   3357 None.
   3358 
   3359 RETURN VALUE
   3360 true/false
   3361 ==========================================================================*/
   3362 bool omx_vdec::execute_output_flush()
   3363 {
   3364     unsigned long p1 = 0; // Parameter - 1
   3365     unsigned long p2 = 0; // Parameter - 2
   3366     unsigned long ident = 0;
   3367     bool bRet = true;
   3368 
   3369     /*Generate FBD for all Buffers in the FTBq*/
   3370     pthread_mutex_lock(&m_lock);
   3371     DEBUG_PRINT_LOW("Initiate Output Flush");
   3372 
   3373     //reset last render TS
   3374     if(m_last_rendered_TS > 0) {
   3375         m_last_rendered_TS = 0;
   3376     }
   3377 
   3378     while (m_ftb_q.m_size) {
   3379         DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
   3380                 m_ftb_q.m_size,pending_output_buffers);
   3381         m_ftb_q.pop_entry(&p1,&p2,&ident);
   3382         DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
   3383         if (ident == m_fill_output_msg ) {
   3384             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
   3385         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   3386             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
   3387         }
   3388     }
   3389     pthread_mutex_unlock(&m_lock);
   3390     output_flush_progress = false;
   3391 
   3392     if (arbitrary_bytes) {
   3393         prev_ts = LLONG_MAX;
   3394         rst_prev_ts = true;
   3395     }
   3396     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   3397     return bRet;
   3398 }
   3399 /*=========================================================================
   3400 FUNCTION : execute_input_flush
   3401 
   3402 DESCRIPTION
   3403 Executes the OMX flush at INPUT PORT.
   3404 
   3405 PARAMETERS
   3406 None.
   3407 
   3408 RETURN VALUE
   3409 true/false
   3410 ==========================================================================*/
   3411 bool omx_vdec::execute_input_flush()
   3412 {
   3413     unsigned       i =0;
   3414     unsigned long p1 = 0; // Parameter - 1
   3415     unsigned long p2 = 0; // Parameter - 2
   3416     unsigned long ident = 0;
   3417     bool bRet = true;
   3418 
   3419     /*Generate EBD for all Buffers in the ETBq*/
   3420     DEBUG_PRINT_LOW("Initiate Input Flush");
   3421 
   3422     pthread_mutex_lock(&m_lock);
   3423     DEBUG_PRINT_LOW("Check if the Queue is empty");
   3424     while (m_etb_q.m_size) {
   3425         m_etb_q.pop_entry(&p1,&p2,&ident);
   3426 
   3427         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   3428             DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   3429             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   3430         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   3431             pending_input_buffers++;
   3432             VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   3433             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   3434                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   3435             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   3436         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   3437             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   3438                     (OMX_BUFFERHEADERTYPE *)p1);
   3439             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   3440         }
   3441     }
   3442     time_stamp_dts.flush_timestamp();
   3443     /*Check if Heap Buffers are to be flushed*/
   3444     if (arbitrary_bytes && !(codec_config_flag)) {
   3445         DEBUG_PRINT_LOW("Reset all the variables before flusing");
   3446         h264_scratch.nFilledLen = 0;
   3447         nal_count = 0;
   3448         look_ahead_nal = false;
   3449         frame_count = 0;
   3450         h264_last_au_ts = LLONG_MAX;
   3451         h264_last_au_flags = 0;
   3452         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   3453         m_demux_entries = 0;
   3454         DEBUG_PRINT_LOW("Initialize parser");
   3455         if (m_frame_parser.mutils) {
   3456             m_frame_parser.mutils->initialize_frame_checking_environment();
   3457         }
   3458 
   3459         while (m_input_pending_q.m_size) {
   3460             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   3461             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   3462         }
   3463 
   3464         if (psource_frame) {
   3465             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   3466             psource_frame = NULL;
   3467         }
   3468 
   3469         if (pdest_frame) {
   3470             pdest_frame->nFilledLen = 0;
   3471             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
   3472                     (unsigned int)NULL);
   3473             pdest_frame = NULL;
   3474         }
   3475         m_frame_parser.flush();
   3476     } else if (codec_config_flag) {
   3477         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   3478                 "is not sent to the driver yet");
   3479     }
   3480     pthread_mutex_unlock(&m_lock);
   3481     input_flush_progress = false;
   3482     if (!arbitrary_bytes) {
   3483         prev_ts = LLONG_MAX;
   3484         rst_prev_ts = true;
   3485     }
   3486 #ifdef _ANDROID_
   3487     if (m_debug_timestamp) {
   3488         m_timestamp_list.reset_ts_list();
   3489     }
   3490 #endif
   3491     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   3492     return bRet;
   3493 }
   3494 
   3495 /*=========================================================================
   3496 FUNCTION : notify_flush_done
   3497 
   3498 DESCRIPTION
   3499 Notifies flush done to the OMX Client.
   3500 
   3501 PARAMETERS
   3502 ctxt -- Context information related to the self..
   3503 
   3504 RETURN VALUE
   3505 NONE
   3506 ==========================================================================*/
   3507 void omx_vdec::notify_flush_done(void *ctxt) {
   3508 
   3509     omx_vdec *pThis = (omx_vdec *) ctxt;
   3510 
   3511     if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
   3512         if (BITMASK_PRESENT(&pThis->m_flags,
   3513                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   3514             DEBUG_PRINT_LOW("Notify Output Flush done");
   3515             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   3516             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3517                 OMX_EventCmdComplete,OMX_CommandFlush,
   3518                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   3519         }
   3520 
   3521         if (BITMASK_PRESENT(&pThis->m_flags,
   3522                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
   3523             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   3524             DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
   3525             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3526                     OMX_EventCmdComplete,OMX_CommandFlush,
   3527                     OMX_CORE_INPUT_PORT_INDEX,NULL );
   3528         }
   3529     }
   3530 }
   3531 
   3532 /* ======================================================================
   3533    FUNCTION
   3534    omx_vdec::SendCommandEvent
   3535 
   3536    DESCRIPTION
   3537    Send the event to decoder pipe.  This is needed to generate the callbacks
   3538    in decoder thread context.
   3539 
   3540    PARAMETERS
   3541    None.
   3542 
   3543    RETURN VALUE
   3544    true/false
   3545 
   3546    ========================================================================== */
   3547 bool omx_vdec::post_event(unsigned long p1,
   3548         unsigned long p2,
   3549         unsigned long id)
   3550 {
   3551     bool bRet = false;
   3552 
   3553     /* Just drop messages typically generated by hardware (w/o client request),
   3554      * if we've reported an error to client. */
   3555     if (m_error_propogated) {
   3556         switch (id) {
   3557             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   3558             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   3559                 DEBUG_PRINT_ERROR("Dropping message %lx "
   3560                         "since client expected to be in error state", id);
   3561                 return false;
   3562             default:
   3563                 /* whatever */
   3564                 break;
   3565         }
   3566     }
   3567 
   3568     pthread_mutex_lock(&m_lock);
   3569 
   3570     if (id == m_fill_output_msg ||
   3571             id == OMX_COMPONENT_GENERATE_FBD ||
   3572             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
   3573             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
   3574         m_ftb_q.insert_entry(p1,p2,id);
   3575     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   3576             id == OMX_COMPONENT_GENERATE_EBD ||
   3577             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
   3578             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
   3579         m_etb_q.insert_entry(p1,p2,id);
   3580     } else {
   3581         m_cmd_q.insert_entry(p1,p2,id);
   3582     }
   3583 
   3584     bRet = true;
   3585     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   3586     post_message(this, id);
   3587 
   3588     pthread_mutex_unlock(&m_lock);
   3589 
   3590     return bRet;
   3591 }
   3592 
   3593 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   3594 {
   3595     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3596     if (!profileLevelType)
   3597         return OMX_ErrorBadParameter;
   3598 
   3599     if (profileLevelType->nPortIndex == 0) {
   3600         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3601             profileLevelType->eLevel = OMX_VIDEO_AVCLevel51;
   3602             if (profileLevelType->nProfileIndex == 0) {
   3603                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3604             } else if (profileLevelType->nProfileIndex == 1) {
   3605                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   3606             } else if (profileLevelType->nProfileIndex == 2) {
   3607                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   3608             } else if (profileLevelType->nProfileIndex == 3) {
   3609                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedBaseline;
   3610             } else if (profileLevelType->nProfileIndex == 4) {
   3611                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedBaseline;
   3612             } else if (profileLevelType->nProfileIndex == 5) {
   3613                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileConstrainedHigh;
   3614             } else if (profileLevelType->nProfileIndex == 6) {
   3615                 profileLevelType->eProfile = QOMX_VIDEO_AVCProfileConstrainedHigh;
   3616             } else {
   3617                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3618                         (unsigned int)profileLevelType->nProfileIndex);
   3619                 eRet = OMX_ErrorNoMore;
   3620             }
   3621         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3622             if (profileLevelType->nProfileIndex == 0) {
   3623                 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
   3624                 profileLevelType->eLevel   = QOMX_VIDEO_MVCLevel51;
   3625             } else {
   3626                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3627                                 (unsigned int)profileLevelType->nProfileIndex);
   3628                 eRet = OMX_ErrorNoMore;
   3629             }
   3630         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3631             if (profileLevelType->nProfileIndex == 0) {
   3632                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
   3633                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3634             } else if (profileLevelType->nProfileIndex == 1) {
   3635                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
   3636                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3637             } else if (profileLevelType->nProfileIndex == 2) {
   3638                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10HDR10;
   3639                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3640             } else {
   3641                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3642                         (unsigned int)profileLevelType->nProfileIndex);
   3643                 eRet = OMX_ErrorNoMore;
   3644             }
   3645         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   3646             if (profileLevelType->nProfileIndex == 0) {
   3647                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   3648                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   3649             } else {
   3650                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3651                                 (unsigned int)profileLevelType->nProfileIndex);
   3652                 eRet = OMX_ErrorNoMore;
   3653             }
   3654         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3655             if (profileLevelType->nProfileIndex == 0) {
   3656                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   3657                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3658             } else if (profileLevelType->nProfileIndex == 1) {
   3659                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   3660                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3661             } else {
   3662                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3663                                 (unsigned int)profileLevelType->nProfileIndex);
   3664                 eRet = OMX_ErrorNoMore;
   3665             }
   3666         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3667                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   3668             eRet = OMX_ErrorNoMore;
   3669         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3670             if (profileLevelType->nProfileIndex == 0) {
   3671                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   3672                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3673             } else if (profileLevelType->nProfileIndex == 1) {
   3674                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   3675                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3676             } else {
   3677                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3678                                 (unsigned int)profileLevelType->nProfileIndex);
   3679                 eRet = OMX_ErrorNoMore;
   3680             }
   3681         } else {
   3682             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
   3683             eRet = OMX_ErrorNoMore;
   3684         }
   3685     } else {
   3686         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
   3687                           (unsigned int)profileLevelType->nPortIndex);
   3688         eRet = OMX_ErrorBadPortIndex;
   3689     }
   3690     return eRet;
   3691 }
   3692 
   3693 /* ======================================================================
   3694    FUNCTION
   3695    omx_vdec::GetParameter
   3696 
   3697    DESCRIPTION
   3698    OMX Get Parameter method implementation
   3699 
   3700    PARAMETERS
   3701    <TBD>.
   3702 
   3703    RETURN VALUE
   3704    Error None if successful.
   3705 
   3706    ========================================================================== */
   3707 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3708         OMX_IN OMX_INDEXTYPE paramIndex,
   3709         OMX_INOUT OMX_PTR     paramData)
   3710 {
   3711     (void) hComp;
   3712     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3713 
   3714     DEBUG_PRINT_LOW("get_parameter:");
   3715     if (m_state == OMX_StateInvalid) {
   3716         DEBUG_PRINT_ERROR("Get Param in Invalid State");
   3717         return OMX_ErrorInvalidState;
   3718     }
   3719     if (paramData == NULL) {
   3720         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
   3721         return OMX_ErrorBadParameter;
   3722     }
   3723     switch ((unsigned long)paramIndex) {
   3724         case OMX_IndexParamPortDefinition: {
   3725                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3726                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   3727                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3728                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   3729                                decide_dpb_buffer_mode(is_down_scalar_enabled);
   3730                                eRet = update_portdef(portDefn);
   3731                                if (eRet == OMX_ErrorNone)
   3732                                    m_port_def = *portDefn;
   3733                                break;
   3734                            }
   3735         case OMX_IndexParamVideoInit: {
   3736                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3737                               OMX_PORT_PARAM_TYPE *portParamType =
   3738                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3739                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   3740 
   3741                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3742                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3743                               portParamType->nPorts           = 2;
   3744                               portParamType->nStartPortNumber = 0;
   3745                               break;
   3746                           }
   3747         case OMX_IndexParamVideoPortFormat: {
   3748                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3749                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3750                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3751                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   3752 
   3753                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   3754                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3755 
   3756                                 if (0 == portFmt->nPortIndex) {
   3757                                     if (0 == portFmt->nIndex) {
   3758                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   3759                                         portFmt->eCompressionFormat = eCompressionFormat;
   3760                                     } else {
   3761                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3762                                                 " NoMore compression formats");
   3763                                         eRet =  OMX_ErrorNoMore;
   3764                                     }
   3765                                 } else if (1 == portFmt->nPortIndex) {
   3766                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   3767 
   3768                                     // Distinguish non-surface mode from normal playback use-case based on
   3769                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
   3770                                     // For non-android, use the default list
   3771                                     // Also use default format-list if FLEXIBLE YUV is supported,
   3772                                     // as the client negotiates the standard color-format if it needs to
   3773                                     bool useNonSurfaceMode = false;
   3774 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
   3775                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
   3776 #endif
   3777                                     if (is_thulium_v1) {
   3778                                         portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3779                                     } else {
   3780                                         portFmt->eColorFormat = useNonSurfaceMode ?
   3781                                             getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
   3782                                             getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3783                                     }
   3784 
   3785                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
   3786                                         eRet = OMX_ErrorNoMore;
   3787                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3788                                                 " NoMore Color formats");
   3789                                     }
   3790                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
   3791                                 } else {
   3792                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   3793                                             (int)portFmt->nPortIndex);
   3794                                     eRet = OMX_ErrorBadPortIndex;
   3795                                 }
   3796                                 break;
   3797                             }
   3798                             /*Component should support this port definition*/
   3799         case OMX_IndexParamAudioInit: {
   3800                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3801                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   3802                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3803                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   3804                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3805                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3806                               audioPortParamType->nPorts           = 0;
   3807                               audioPortParamType->nStartPortNumber = 0;
   3808                               break;
   3809                           }
   3810                           /*Component should support this port definition*/
   3811         case OMX_IndexParamImageInit: {
   3812                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3813                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   3814                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3815                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   3816                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3817                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3818                               imagePortParamType->nPorts           = 0;
   3819                               imagePortParamType->nStartPortNumber = 0;
   3820                               break;
   3821 
   3822                           }
   3823                           /*Component should support this port definition*/
   3824         case OMX_IndexParamOtherInit: {
   3825                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
   3826                                       paramIndex);
   3827                               eRet =OMX_ErrorUnsupportedIndex;
   3828                               break;
   3829                           }
   3830         case OMX_IndexParamStandardComponentRole: {
   3831                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   3832                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3833                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3834                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   3835                                   comp_role->nSize = sizeof(*comp_role);
   3836 
   3837                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
   3838                                           paramIndex);
   3839                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   3840                                           OMX_MAX_STRINGNAME_SIZE);
   3841                                   break;
   3842                               }
   3843                               /* Added for parameter test */
   3844         case OMX_IndexParamPriorityMgmt: {
   3845                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   3846                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   3847                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   3848                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   3849                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   3850                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
   3851 
   3852                              break;
   3853                          }
   3854                          /* Added for parameter test */
   3855         case OMX_IndexParamCompBufferSupplier: {
   3856                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   3857                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   3858                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3859                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   3860 
   3861                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
   3862                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   3863                                    if (0 == bufferSupplierType->nPortIndex)
   3864                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3865                                    else if (1 == bufferSupplierType->nPortIndex)
   3866                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3867                                    else
   3868                                        eRet = OMX_ErrorBadPortIndex;
   3869 
   3870 
   3871                                    break;
   3872                                }
   3873         case OMX_IndexParamVideoAvc: {
   3874                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
   3875                                      paramIndex);
   3876                              break;
   3877                          }
   3878         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3879                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
   3880                                      paramIndex);
   3881                              break;
   3882                          }
   3883         case OMX_IndexParamVideoH263: {
   3884                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   3885                                       paramIndex);
   3886                               break;
   3887                           }
   3888         case OMX_IndexParamVideoMpeg4: {
   3889                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   3890                                        paramIndex);
   3891                                break;
   3892                            }
   3893         case OMX_IndexParamVideoMpeg2: {
   3894                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   3895                                        paramIndex);
   3896                                break;
   3897                            }
   3898         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   3899                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3900                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
   3901                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   3902                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   3903                                         eRet = get_supported_profile_level(profileLevelType);
   3904                                         break;
   3905                                     }
   3906 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3907         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   3908                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
   3909                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   3910                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   3911                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3912 
   3913                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
   3914                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   3915                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   3916                                             } else {
   3917                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
   3918                                             }
   3919                                         } else {
   3920                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   3921                                             eRet = OMX_ErrorBadParameter;
   3922                                         }
   3923                                     }
   3924                                     break;
   3925 #endif
   3926 
   3927 #ifdef FLEXYUV_SUPPORTED
   3928         case OMX_QcomIndexFlexibleYUVDescription: {
   3929                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
   3930                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
   3931                 eRet = describeColorFormat(paramData);
   3932                 break;
   3933             }
   3934 #endif
   3935         case OMX_IndexParamVideoProfileLevelCurrent: {
   3936              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3937              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3938              struct v4l2_control profile_control, level_control;
   3939 
   3940              switch (drv_ctx.decoder_format) {
   3941                  case VDEC_CODECTYPE_H264:
   3942                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   3943                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   3944                      break;
   3945                  default:
   3946                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
   3947                      eRet = OMX_ErrorNotImplemented;
   3948                      break;
   3949              }
   3950 
   3951              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
   3952                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
   3953                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   3954                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   3955                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3956                         break;
   3957                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   3958                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
   3959                         break;
   3960                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   3961                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
   3962                         break;
   3963                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   3964                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
   3965                         break;
   3966                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   3967                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
   3968                         break;
   3969                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   3970                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
   3971                         break;
   3972                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   3973                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
   3974                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
   3975                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
   3976                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
   3977                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
   3978                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
   3979                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
   3980                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
   3981                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
   3982                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   3983                         eRet = OMX_ErrorUnsupportedIndex;
   3984                         break;
   3985                 }
   3986              } else {
   3987                  eRet = OMX_ErrorUnsupportedIndex;
   3988              }
   3989 
   3990 
   3991              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
   3992                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
   3993                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   3994                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
   3995                         break;
   3996                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   3997                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
   3998                         break;
   3999                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   4000                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
   4001                         break;
   4002                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   4003                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
   4004                         break;
   4005                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   4006                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
   4007                         break;
   4008                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   4009                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
   4010                         break;
   4011                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   4012                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
   4013                         break;
   4014                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   4015                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
   4016                         break;
   4017                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   4018                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
   4019                         break;
   4020                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   4021                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
   4022                         break;
   4023                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   4024                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
   4025                         break;
   4026                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   4027                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
   4028                         break;
   4029                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   4030                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
   4031                         break;
   4032                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   4033                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
   4034                         break;
   4035                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   4036                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
   4037                         break;
   4038                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   4039                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
   4040                         break;
   4041                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   4042                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
   4043                         break;
   4044                 }
   4045              } else {
   4046                  eRet = OMX_ErrorUnsupportedIndex;
   4047              }
   4048 
   4049              break;
   4050 
   4051          }
   4052         case OMX_QTIIndexParamVideoClientExtradata:
   4053         {
   4054             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
   4055             DEBUG_PRINT_LOW("get_parameter: OMX_QTIIndexParamVideoClientExtradata");
   4056             QOMX_EXTRADATA_ENABLE *pParam =
   4057                 (QOMX_EXTRADATA_ENABLE *)paramData;
   4058             if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   4059                 pParam->bEnable = client_extradata ? OMX_TRUE : OMX_FALSE;
   4060                 eRet = OMX_ErrorNone;
   4061             } else {
   4062                 eRet = OMX_ErrorUnsupportedIndex;
   4063             }
   4064             break;
   4065         }
   4066         case OMX_QTIIndexParamDitherControl:
   4067         {
   4068             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DITHER_CONTROL);
   4069             DEBUG_PRINT_LOW("get_parameter: QOMX_VIDEO_DITHER_CONTROL");
   4070             QOMX_VIDEO_DITHER_CONTROL *pParam =
   4071                 (QOMX_VIDEO_DITHER_CONTROL *) paramData;
   4072             pParam->eDitherType = (QOMX_VIDEO_DITHERTYPE) m_dither_config;
   4073             eRet = OMX_ErrorNone;
   4074             break;
   4075         }
   4076         default: {
   4077                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
   4078                  eRet =OMX_ErrorUnsupportedIndex;
   4079              }
   4080 
   4081     }
   4082 
   4083     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
   4084             drv_ctx.video_resolution.frame_width,
   4085             drv_ctx.video_resolution.frame_height,
   4086             drv_ctx.video_resolution.stride,
   4087             drv_ctx.video_resolution.scan_lines);
   4088 
   4089     return eRet;
   4090 }
   4091 
   4092 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4093 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   4094 {
   4095     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   4096     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4097     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   4098 
   4099     if ((params == NULL) ||
   4100             (params->nativeBuffer == NULL) ||
   4101             (params->nativeBuffer->handle == NULL) ||
   4102             !m_enable_android_native_buffers)
   4103         return OMX_ErrorBadParameter;
   4104     m_use_android_native_buffers = OMX_TRUE;
   4105     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   4106     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   4107     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   4108         OMX_U8 *buffer = NULL;
   4109         if (!secure_mode) {
   4110             buffer = (OMX_U8*)mmap(0, handle->size,
   4111                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   4112             if (buffer == MAP_FAILED) {
   4113                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   4114                 return OMX_ErrorInsufficientResources;
   4115             }
   4116         }
   4117         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   4118     } else {
   4119         eRet = OMX_ErrorBadParameter;
   4120     }
   4121     return eRet;
   4122 }
   4123 #endif
   4124 
   4125 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
   4126     struct v4l2_control control;
   4127     struct v4l2_format fmt;
   4128     control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   4129     control.value = 1;
   4130     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   4131     if (rc < 0) {
   4132         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   4133         return OMX_ErrorHardware;
   4134     }
   4135     m_smoothstreaming_mode = true;
   4136     return OMX_ErrorNone;
   4137 }
   4138 
   4139 /* ======================================================================
   4140    FUNCTION
   4141    omx_vdec::Setparameter
   4142 
   4143    DESCRIPTION
   4144    OMX Set Parameter method implementation.
   4145 
   4146    PARAMETERS
   4147    <TBD>.
   4148 
   4149    RETURN VALUE
   4150    OMX Error None if successful.
   4151 
   4152    ========================================================================== */
   4153 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   4154         OMX_IN OMX_INDEXTYPE paramIndex,
   4155         OMX_IN OMX_PTR        paramData)
   4156 {
   4157     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4158     int ret=0;
   4159     struct v4l2_format fmt;
   4160 #ifdef _ANDROID_
   4161     char property_value[PROPERTY_VALUE_MAX] = {0};
   4162 #endif
   4163     if (m_state == OMX_StateInvalid) {
   4164         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   4165         return OMX_ErrorInvalidState;
   4166     }
   4167     if (paramData == NULL) {
   4168         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   4169         return OMX_ErrorBadParameter;
   4170     }
   4171     if ((m_state != OMX_StateLoaded) &&
   4172             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   4173             (m_out_bEnabled == OMX_TRUE) &&
   4174             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   4175             (m_inp_bEnabled == OMX_TRUE)) {
   4176         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   4177         return OMX_ErrorIncorrectStateOperation;
   4178     }
   4179     switch ((unsigned long)paramIndex) {
   4180         case OMX_IndexParamPortDefinition: {
   4181                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   4182                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   4183                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   4184                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   4185                                //been called.
   4186                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
   4187                                        (int)portDefn->format.video.nFrameHeight,
   4188                                        (int)portDefn->format.video.nFrameWidth);
   4189 
   4190                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4191                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
   4192                                                           portDefn->nBufferCountActual);
   4193                                    eRet = OMX_ErrorBadParameter;
   4194                                    break;
   4195                                }
   4196                                if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
   4197                                    if (portDefn->nBufferCountActual < MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS ||
   4198                                         portDefn->nBufferSize != m_client_out_extradata_info.getSize()) {
   4199                                         DEBUG_PRINT_ERROR("ERROR: Bad parameeters request for extradata limit %d size - %d",
   4200                                                           portDefn->nBufferCountActual, portDefn->nBufferSize);
   4201                                         eRet = OMX_ErrorBadParameter;
   4202                                         break;
   4203                                    }
   4204                                     m_client_out_extradata_info.set_extradata_info(portDefn->nBufferSize,
   4205                                             portDefn->nBufferCountActual);
   4206                                     break;
   4207                                }
   4208 
   4209                                if (OMX_DirOutput == portDefn->eDir) {
   4210                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
   4211                                    bool port_format_changed = false;
   4212                                    m_display_id = portDefn->format.video.pNativeWindow;
   4213                                    unsigned int buffer_size;
   4214                                    /* update output port resolution with client supplied dimensions
   4215                                       in case scaling is enabled, else it follows input resolution set
   4216                                    */
   4217                                    decide_dpb_buffer_mode(is_down_scalar_enabled);
   4218                                    if (is_down_scalar_enabled) {
   4219                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
   4220                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4221                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4222                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   4223                                                portDefn->format.video.nFrameWidth != 0x0) {
   4224                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4225                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4226                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   4227                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   4228                                            if (ret) {
   4229                                                DEBUG_PRINT_ERROR("Get Resolution failed");
   4230                                                eRet = OMX_ErrorHardware;
   4231                                                break;
   4232                                            }
   4233                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
   4234                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
   4235                                                    port_format_changed = true;
   4236                                            }
   4237 
   4238                                            /* set crop info */
   4239                                            rectangle.nLeft = 0;
   4240                                            rectangle.nTop = 0;
   4241                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
   4242                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
   4243 
   4244                                            m_extradata_info.output_crop_rect.nLeft = 0;
   4245                                            m_extradata_info.output_crop_rect.nTop = 0;
   4246                                            m_extradata_info.output_crop_rect.nWidth = rectangle.nWidth;
   4247                                            m_extradata_info.output_crop_rect.nHeight = rectangle.nHeight;
   4248 
   4249                                            eRet = is_video_session_supported();
   4250                                            if (eRet)
   4251                                                break;
   4252                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4253                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4254                                            fmt.fmt.pix_mp.height = (unsigned int)portDefn->format.video.nFrameHeight;
   4255                                            fmt.fmt.pix_mp.width = (unsigned int)portDefn->format.video.nFrameWidth;
   4256                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   4257                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
   4258                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
   4259                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4260                                            if (ret) {
   4261                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4262                                                eRet = OMX_ErrorUnsupportedSetting;
   4263                                            } else
   4264                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   4265                                        }
   4266 
   4267                                        if (eRet) {
   4268                                            break;
   4269                                        }
   4270 
   4271                                        if (secure_mode) {
   4272                                            struct v4l2_control control;
   4273                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
   4274                                            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   4275                                                DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
   4276                                                eRet = OMX_ErrorHardware;
   4277                                            } else {
   4278                                                /* This is a workaround for a bug in fw which uses stride
   4279                                                 * and slice instead of width and height to check against
   4280                                                 * the threshold.
   4281                                                 */
   4282                                                OMX_U32 stride, slice;
   4283                                                if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   4284                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
   4285                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
   4286                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   4287                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth);
   4288                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight);
   4289                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   4290                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameWidth);
   4291                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, portDefn->format.video.nFrameHeight);
   4292                                                } else {
   4293                                                    stride = portDefn->format.video.nFrameWidth;
   4294                                                    slice = portDefn->format.video.nFrameHeight;
   4295                                                }
   4296 
   4297                                                DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
   4298                                                DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
   4299 
   4300                                                if (stride * slice <= (OMX_U32)control.value) {
   4301                                                    secure_scaling_to_non_secure_opb = true;
   4302                                                    DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
   4303                                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
   4304                                                    control.value = 1;
   4305                                                    if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   4306                                                        DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
   4307                                                        eRet = OMX_ErrorUnsupportedSetting;
   4308                                                    }
   4309                                                }
   4310                                            }
   4311                                        }
   4312                                    }
   4313 
   4314                                    if (eRet) {
   4315                                        break;
   4316                                    }
   4317 
   4318                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4319                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
   4320                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4321                                        eRet = OMX_ErrorBadParameter;
   4322                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
   4323                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
   4324                                        eRet = OMX_ErrorBadParameter;
   4325                                    } else if (!port_format_changed) {
   4326 
   4327                                        // Buffer count can change only when port is unallocated
   4328                                        if (m_out_mem_ptr &&
   4329                                                 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
   4330                                                 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
   4331 
   4332                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
   4333                                            eRet = OMX_ErrorInvalidState;
   4334                                            break;
   4335                                        }
   4336 
   4337                                        // route updating of buffer requirements via c2d proxy.
   4338                                        // Based on whether c2d is enabled, requirements will be handed
   4339                                        // to the vidc driver appropriately
   4340                                        eRet = client_buffers.set_buffer_req(portDefn->nBufferSize,
   4341                                                 portDefn->nBufferCountActual);
   4342                                        if (eRet == OMX_ErrorNone) {
   4343                                            m_port_def = *portDefn;
   4344                                        } else {
   4345                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
   4346                                                    drv_ctx.op_buf.mincount, (unsigned int)buffer_size,
   4347                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4348                                            eRet = OMX_ErrorBadParameter;
   4349                                        }
   4350                                    }
   4351                                } else if (OMX_DirInput == portDefn->eDir) {
   4352                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
   4353                                    bool port_format_changed = false;
   4354                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   4355                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   4356                                        // Frame rate only should be set if this is a "known value" or to
   4357                                        // activate ts prediction logic (arbitrary mode only) sending input
   4358                                        // timestamps with max value (LLONG_MAX).
   4359                                        m_fps_received = portDefn->format.video.xFramerate;
   4360                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
   4361                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
   4362                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   4363                                                drv_ctx.frame_rate.fps_denominator);
   4364                                        if (!drv_ctx.frame_rate.fps_numerator) {
   4365                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   4366                                            drv_ctx.frame_rate.fps_numerator = 30;
   4367                                        }
   4368                                        if (drv_ctx.frame_rate.fps_denominator)
   4369                                            drv_ctx.frame_rate.fps_numerator = (int)
   4370                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   4371                                        drv_ctx.frame_rate.fps_denominator = 1;
   4372                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   4373                                            drv_ctx.frame_rate.fps_numerator;
   4374                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
   4375                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   4376                                                (float)drv_ctx.frame_rate.fps_denominator);
   4377 
   4378                                        struct v4l2_outputparm oparm;
   4379                                        /*XXX: we're providing timing info as seconds per frame rather than frames
   4380                                         * per second.*/
   4381                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   4382                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   4383 
   4384                                        struct v4l2_streamparm sparm;
   4385                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4386                                        sparm.parm.output = oparm;
   4387                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   4388                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
   4389                                            eRet = OMX_ErrorHardware;
   4390                                            break;
   4391                                        }
   4392                                        m_perf_control.request_cores(frm_int);
   4393                                    }
   4394 
   4395                                    if (drv_ctx.video_resolution.frame_height !=
   4396                                            portDefn->format.video.nFrameHeight ||
   4397                                            drv_ctx.video_resolution.frame_width  !=
   4398                                            portDefn->format.video.nFrameWidth) {
   4399                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
   4400                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4401                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4402                                        port_format_changed = true;
   4403                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
   4404                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
   4405                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
   4406                                            if (m_smoothstreaming_mode &&
   4407                                                    ((frameWidth * frameHeight) <
   4408                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
   4409                                                frameWidth = m_smoothstreaming_width;
   4410                                                frameHeight = m_smoothstreaming_height;
   4411                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
   4412                                                        "for adaptive-playback/smooth-streaming",
   4413                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
   4414                                            }
   4415 
   4416                                            m_extradata_info.output_crop_rect.nLeft = 0;
   4417                                            m_extradata_info.output_crop_rect.nTop = 0;
   4418                                            m_extradata_info.output_crop_rect.nWidth = frameWidth;
   4419                                            m_extradata_info.output_crop_rect.nHeight = frameHeight;
   4420 
   4421                                            update_resolution(frameWidth, frameHeight,
   4422                                                    frameWidth, frameHeight);
   4423                                            eRet = is_video_session_supported();
   4424                                            if (eRet)
   4425                                                break;
   4426                                            if (is_down_scalar_enabled) {
   4427                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4428                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4429                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4430                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4431                                                fmt.fmt.pix_mp.pixelformat = output_capability;
   4432                                                DEBUG_PRINT_LOW("DS Enabled : height = %d , width = %d",
   4433                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4434                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4435                                            } else {
   4436                                                memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4437                                                fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4438                                                fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4439                                                fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4440                                                fmt.fmt.pix_mp.pixelformat = output_capability;
   4441                                                DEBUG_PRINT_LOW("DS Disabled : height = %d , width = %d",
   4442                                                    fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4443                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4444                                                fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4445                                                fmt.fmt.pix_mp.pixelformat = capture_capability;
   4446                                                ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4447                                            }
   4448                                            if (ret) {
   4449                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4450                                                eRet = OMX_ErrorUnsupportedSetting;
   4451                                            } else {
   4452                                                if (!is_down_scalar_enabled)
   4453                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
   4454                                            }
   4455                                        }
   4456                                    }
   4457                                    if (m_custom_buffersize.input_buffersize
   4458                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
   4459                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
   4460                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
   4461                                        eRet = OMX_ErrorBadParameter;
   4462                                        break;
   4463                                    }
   4464                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4465                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
   4466                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4467                                        eRet = OMX_ErrorBadParameter;
   4468                                        break;
   4469                                    }
   4470                                    // Buffer count can change only when port is unallocated
   4471                                    if (m_inp_mem_ptr &&
   4472                                             (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
   4473                                             portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
   4474                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
   4475                                        eRet = OMX_ErrorInvalidState;
   4476                                        break;
   4477                                    }
   4478 
   4479                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   4480                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   4481                                        port_format_changed = true;
   4482                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   4483                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   4484                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   4485                                            (~(buffer_prop->alignment - 1));
   4486                                        eRet = set_buffer_req(buffer_prop);
   4487                                    }
   4488                                    if (false == port_format_changed) {
   4489                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
   4490                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
   4491                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4492                                        eRet = OMX_ErrorBadParameter;
   4493                                    }
   4494                                } else if (portDefn->eDir ==  OMX_DirMax) {
   4495                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   4496                                            (int)portDefn->nPortIndex);
   4497                                    eRet = OMX_ErrorBadPortIndex;
   4498                                }
   4499                            }
   4500                            break;
   4501         case OMX_IndexParamVideoPortFormat: {
   4502                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   4503                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   4504                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   4505                                 int ret=0;
   4506                                 struct v4l2_format fmt;
   4507                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
   4508                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
   4509 
   4510                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4511                                 if (1 == portFmt->nPortIndex) {
   4512                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4513                                     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   4514                                     if (ret < 0) {
   4515                                         DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   4516                                         return OMX_ErrorBadParameter;
   4517                                     }
   4518                                     enum vdec_output_fromat op_format;
   4519                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4520                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   4521                                             portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4522                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
   4523                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
   4524                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   4525                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   4526                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4527                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4528                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC;
   4529                                     } else
   4530                                         eRet = OMX_ErrorBadParameter;
   4531 
   4532                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4533                                             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4534                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   4535                                     } else {
   4536                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
   4537                                     }
   4538 
   4539                                     if (eRet == OMX_ErrorNone) {
   4540                                         drv_ctx.output_format = op_format;
   4541                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4542                                         if (ret) {
   4543                                             DEBUG_PRINT_ERROR("Set output format failed");
   4544                                             eRet = OMX_ErrorUnsupportedSetting;
   4545                                             /*TODO: How to handle this case */
   4546                                         } else {
   4547                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   4548                                         }
   4549                                     }
   4550                                     if (eRet == OMX_ErrorNone) {
   4551                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   4552                                             DEBUG_PRINT_ERROR("Set color format failed");
   4553                                             eRet = OMX_ErrorBadParameter;
   4554                                         }
   4555                                     }
   4556                                 }
   4557                             }
   4558                             break;
   4559 
   4560         case OMX_QcomIndexPortDefn: {
   4561                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
   4562                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   4563                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   4564                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
   4565                                     (unsigned int)portFmt->nFramePackingFormat);
   4566 
   4567                             /* Input port */
   4568                             if (portFmt->nPortIndex == 0) {
   4569                                 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
   4570                                 //   - headers are allocated and
   4571                                 //   - headers-indices are derived
   4572                                 // Avoid changing arbitrary_bytes when the port is already allocated
   4573                                 if (m_inp_mem_ptr) {
   4574                                     DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
   4575                                     return OMX_ErrorUnsupportedSetting;
   4576                                 }
   4577                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   4578                                     if (secure_mode || m_input_pass_buffer_fd) {
   4579                                         arbitrary_bytes = false;
   4580                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
   4581                                         eRet = OMX_ErrorUnsupportedSetting;
   4582                                     } else {
   4583                                         arbitrary_bytes = true;
   4584                                     }
   4585                                 } else if (portFmt->nFramePackingFormat ==
   4586                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   4587                                     arbitrary_bytes = false;
   4588 #ifdef _ANDROID_
   4589                                     property_get("vendor.vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   4590                                     if (atoi(property_value)) {
   4591                                         DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
   4592                                         arbitrary_bytes = true;
   4593                                     }
   4594 #endif
   4595                                 } else {
   4596                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
   4597                                             (unsigned int)portFmt->nFramePackingFormat);
   4598                                     eRet = OMX_ErrorUnsupportedSetting;
   4599                                 }
   4600                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4601                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
   4602                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   4603                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   4604                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   4605                                     m_out_mem_region_smi = OMX_TRUE;
   4606                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4607                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
   4608                                         m_use_output_pmem = OMX_TRUE;
   4609                                     }
   4610                                 }
   4611                             }
   4612                         }
   4613                         if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   4614                                     OMX_MAX_STRINGNAME_SIZE)) {
   4615                             arbitrary_bytes = true;
   4616                             DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264");
   4617                         }
   4618                         break;
   4619 
   4620         case OMX_QTIIndexParamVideoClientExtradata: {
   4621                                   VALIDATE_OMX_PARAM_DATA(paramData, QOMX_EXTRADATA_ENABLE);
   4622                                   DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoClientExtradata");
   4623                                   QOMX_EXTRADATA_ENABLE *pParam =
   4624                                       (QOMX_EXTRADATA_ENABLE *)paramData;
   4625 
   4626                                   if (m_state != OMX_StateLoaded) {
   4627                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid state");
   4628                                       return OMX_ErrorIncorrectStateOperation;
   4629                                   }
   4630 
   4631                                   if (pParam->nPortIndex == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   4632                                       m_client_out_extradata_info.enable_client_extradata(pParam->bEnable);
   4633                                   } else {
   4634                                       DEBUG_PRINT_ERROR("Incorrect portIndex - %d", pParam->nPortIndex);
   4635                                       eRet = OMX_ErrorUnsupportedIndex;
   4636                                   }
   4637                                   break;
   4638                               }
   4639         case OMX_IndexParamStandardComponentRole: {
   4640                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   4641                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   4642                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   4643                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
   4644                                           comp_role->cRole);
   4645 
   4646                                   if ((m_state == OMX_StateLoaded)&&
   4647                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
   4648                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   4649                                   } else {
   4650                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4651                                       return OMX_ErrorIncorrectStateOperation;
   4652                                   }
   4653 
   4654                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4655                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4656                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
   4657                                       } else {
   4658                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4659                                           eRet =OMX_ErrorUnsupportedSetting;
   4660                                       }
   4661                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4662                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4663                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   4664                                       } else {
   4665                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4666                                           eRet = OMX_ErrorUnsupportedSetting;
   4667                                       }
   4668                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4669                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4670                                           strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
   4671                                       } else {
   4672                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4673                                           eRet = OMX_ErrorUnsupportedSetting;
   4674                                       }
   4675                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4676                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4677                                           strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
   4678                                       } else {
   4679                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4680                                           eRet =OMX_ErrorUnsupportedSetting;
   4681                                       }
   4682                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4683                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4684                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
   4685                                       } else {
   4686                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4687                                           eRet = OMX_ErrorUnsupportedSetting;
   4688                                       }
   4689                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) ||
   4690                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
   4691                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
   4692                                         ) {
   4693                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) {
   4694                                           strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
   4695                                       } else {
   4696                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4697                                           eRet =OMX_ErrorUnsupportedSetting;
   4698                                       }
   4699                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) ||
   4700                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE))
   4701                                         ) {
   4702                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   4703                                           strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
   4704                                       } else {
   4705                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4706                                           eRet =OMX_ErrorUnsupportedSetting;
   4707                                       }
   4708                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   4709                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   4710                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4711                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
   4712                                       } else {
   4713                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4714                                           eRet = OMX_ErrorUnsupportedSetting;
   4715                                       }
   4716                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   4717                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
   4718                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4719                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
   4720                                       } else {
   4721                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4722                                           eRet = OMX_ErrorUnsupportedSetting;
   4723                                       }
   4724                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4725                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4726                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   4727                                       } else {
   4728                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4729                                           eRet = OMX_ErrorUnsupportedSetting;
   4730                                       }
   4731                                   } else {
   4732                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
   4733                                       eRet = OMX_ErrorInvalidComponentName;
   4734                                   }
   4735                                   break;
   4736                               }
   4737 
   4738         case OMX_IndexParamPriorityMgmt: {
   4739                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   4740                              if (m_state != OMX_StateLoaded) {
   4741                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4742                                  return OMX_ErrorIncorrectStateOperation;
   4743                              }
   4744                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   4745                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
   4746                                      (unsigned int)priorityMgmtype->nGroupID);
   4747 
   4748                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
   4749                                      (unsigned int)priorityMgmtype->nGroupPriority);
   4750 
   4751                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   4752                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   4753 
   4754                              break;
   4755                          }
   4756 
   4757         case OMX_IndexParamCompBufferSupplier: {
   4758                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   4759                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   4760                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
   4761                                            bufferSupplierType->eBufferSupplier);
   4762                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   4763                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   4764 
   4765                                    else
   4766 
   4767                                        eRet = OMX_ErrorBadPortIndex;
   4768 
   4769                                    break;
   4770 
   4771                                }
   4772         case OMX_IndexParamVideoAvc: {
   4773                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
   4774                                      paramIndex);
   4775                              break;
   4776                          }
   4777         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   4778                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
   4779                                      paramIndex);
   4780                              break;
   4781                         }
   4782         case OMX_IndexParamVideoH263: {
   4783                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   4784                                       paramIndex);
   4785                               break;
   4786                           }
   4787         case OMX_IndexParamVideoMpeg4: {
   4788                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   4789                                        paramIndex);
   4790                                break;
   4791                            }
   4792         case OMX_IndexParamVideoMpeg2: {
   4793                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   4794                                        paramIndex);
   4795                                break;
   4796                            }
   4797         case OMX_QTIIndexParamLowLatencyMode: {
   4798                                struct v4l2_control control;
   4799                                int rc = 0;
   4800                                QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE* pParam =
   4801                                    (QOMX_EXTNINDEX_VIDEO_VENC_LOW_LATENCY_MODE*)paramData;
   4802                                if (pParam->bLowLatencyMode) {
   4803                                    DEBUG_PRINT_HIGH("Enabling DECODE order");
   4804                                    time_stamp_dts.set_timestamp_reorder_mode(false);
   4805                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4806                                    control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4807                                    rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4808                                    if (rc) {
   4809                                        DEBUG_PRINT_ERROR("Set picture order failed");
   4810                                        eRet = OMX_ErrorUnsupportedSetting;
   4811                                    }
   4812                                }
   4813                                break;
   4814                            }
   4815         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   4816                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
   4817                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   4818                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   4819                                      struct v4l2_control control;
   4820                                      int pic_order,rc=0;
   4821                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
   4822                                              pictureOrder->eOutputPictureOrder);
   4823                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   4824                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   4825                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   4826                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4827                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   4828                                      } else
   4829                                          eRet = OMX_ErrorBadParameter;
   4830                                      if (eRet == OMX_ErrorNone) {
   4831                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4832                                          control.value = pic_order;
   4833                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4834                                          if (rc) {
   4835                                              DEBUG_PRINT_ERROR("Set picture order failed");
   4836                                              eRet = OMX_ErrorUnsupportedSetting;
   4837                                          }
   4838                                      }
   4839                                      m_decode_order_mode =
   4840                                             pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
   4841                                      break;
   4842                                  }
   4843         case OMX_QcomIndexParamConcealMBMapExtraData:
   4844                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4845                                eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   4846                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4847                                break;
   4848         case OMX_QcomIndexParamFrameInfoExtraData:
   4849                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4850                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   4851                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4852                                break;
   4853         case OMX_ExtraDataFrameDimension:
   4854                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4855                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
   4856                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4857                                break;
   4858         case OMX_QcomIndexParamInterlaceExtraData:
   4859                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4860                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   4861                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4862                                break;
   4863         case OMX_QcomIndexParamH264TimeInfo:
   4864                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4865                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   4866                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4867                                break;
   4868         case OMX_QcomIndexParamVideoFramePackingExtradata:
   4869                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4870                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
   4871                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4872                                break;
   4873         case OMX_QcomIndexParamVideoQPExtraData:
   4874                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4875                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4876                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4877                                break;
   4878         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
   4879                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4880                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
   4881                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4882                                break;
   4883         case OMX_QcomIndexEnableExtnUserData:
   4884                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4885                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
   4886                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4887                                 break;
   4888         case OMX_QTIIndexParamVQZipSEIExtraData:
   4889                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4890                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4891                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4892                                 break;
   4893         case OMX_QcomIndexParamVideoDivx: {
   4894                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   4895                           }
   4896                           break;
   4897         case OMX_QcomIndexPlatformPvt: {
   4898                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN);
   4899                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
   4900                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   4901                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4902                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   4903                                    eRet = OMX_ErrorUnsupportedSetting;
   4904                                } else {
   4905                                    m_out_pvt_entry_pmem = OMX_TRUE;
   4906                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4907                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
   4908                                        m_use_output_pmem = OMX_TRUE;
   4909                                    }
   4910                                }
   4911 
   4912                            }
   4913                            break;
   4914         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   4915                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   4916                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   4917                                        struct v4l2_control control;
   4918                                        int rc;
   4919                                        drv_ctx.idr_only_decoding = 1;
   4920                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4921                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4922                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4923                                        if (rc) {
   4924                                            DEBUG_PRINT_ERROR("Set picture order failed");
   4925                                            eRet = OMX_ErrorUnsupportedSetting;
   4926                                        } else {
   4927                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   4928                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   4929                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4930                                            if (rc) {
   4931                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
   4932                                                eRet = OMX_ErrorUnsupportedSetting;
   4933                                            }
   4934                                            /*Setting sync frame decoding on driver might change buffer
   4935                                             * requirements so update them here*/
   4936                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   4937                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
   4938                                                eRet = OMX_ErrorUnsupportedSetting;
   4939                                            }
   4940                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   4941                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
   4942                                                eRet = OMX_ErrorUnsupportedSetting;
   4943                                            }
   4944                                        }
   4945                                    }
   4946                                    break;
   4947 
   4948         case OMX_QcomIndexParamIndexExtraDataType: {
   4949                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
   4950                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   4951                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   4952                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
   4953                                             (extradataIndexType->nPortIndex == 1)) {
   4954                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
   4955                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   4956 
   4957                                     }
   4958                                 }
   4959                                 break;
   4960         case OMX_QcomIndexParamEnableSmoothStreaming: {
   4961 #ifndef SMOOTH_STREAMING_DISABLED
   4962                                       eRet = enable_smoothstreaming();
   4963 #else
   4964                                       eRet = OMX_ErrorUnsupportedSetting;
   4965 #endif
   4966                                   }
   4967                                   break;
   4968 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4969                                   /* Need to allow following two set_parameters even in Idle
   4970                                    * state. This is ANDROID architecture which is not in sync
   4971                                    * with openmax standard. */
   4972         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   4973                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
   4974                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   4975                                            if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   4976                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
   4977                                                 eRet = OMX_ErrorUnsupportedSetting;
   4978                                                 break;
   4979                                            } else if (m_out_mem_ptr) {
   4980                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
   4981                                                 eRet = OMX_ErrorInvalidState;
   4982                                                 break;
   4983                                            }
   4984                                            if (enableNativeBuffers) {
   4985                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   4986                                            }
   4987 #if !defined(FLEXYUV_SUPPORTED)
   4988                                            if (m_enable_android_native_buffers) {
   4989                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
   4990                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
   4991                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
   4992                                                    eRet = OMX_ErrorUnsupportedSetting;
   4993                                                }
   4994                                            }
   4995 #endif
   4996                                        }
   4997                                        break;
   4998         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   4999                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
   5000                                        eRet = use_android_native_buffer(hComp, paramData);
   5001                                    }
   5002                                    break;
   5003 #if ALLOCATE_OUTPUT_NATIVEHANDLE
   5004         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
   5005 
   5006                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
   5007                 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
   5008 
   5009                 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   5010                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!");
   5011                     eRet = OMX_ErrorUnsupportedSetting;
   5012                     break;
   5013                 } else if (m_inp_mem_ptr) {
   5014                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
   5015                     eRet = OMX_ErrorInvalidState;
   5016                     break;
   5017                 }
   5018 
   5019                 if (allocateNativeHandleParams != NULL) {
   5020                     allocate_native_handle = allocateNativeHandleParams->enable;
   5021                 }
   5022             }
   5023             break;
   5024 #endif //ALLOCATE_OUTPUT_NATIVEHANDLE
   5025 #endif
   5026         case OMX_QcomIndexParamEnableTimeStampReorder: {
   5027                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
   5028                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   5029                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   5030                                            if (reorder->bEnable == OMX_TRUE) {
   5031                                                frm_int =0;
   5032                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   5033                                            } else
   5034                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   5035                                        } else {
   5036                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   5037                                            if (reorder->bEnable == OMX_TRUE) {
   5038                                                eRet = OMX_ErrorUnsupportedSetting;
   5039                                            }
   5040                                        }
   5041                                    }
   5042                                    break;
   5043         case OMX_IndexParamVideoProfileLevelCurrent: {
   5044                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   5045                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   5046                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   5047                                      if (pParam) {
   5048                                          m_profile_lvl.eProfile = pParam->eProfile;
   5049                                          m_profile_lvl.eLevel = pParam->eLevel;
   5050                                      }
   5051                                      break;
   5052 
   5053                                  }
   5054         case OMX_QcomIndexParamVideoMetaBufferMode:
   5055         {
   5056             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
   5057             StoreMetaDataInBuffersParams *metabuffer =
   5058                 (StoreMetaDataInBuffersParams *)paramData;
   5059             if (!metabuffer) {
   5060                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   5061                 eRet = OMX_ErrorBadParameter;
   5062                 break;
   5063             }
   5064             if (m_disable_dynamic_buf_mode) {
   5065                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
   5066                 eRet = OMX_ErrorUnsupportedSetting;
   5067                 break;
   5068             }
   5069             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   5070 
   5071                     if (m_out_mem_ptr) {
   5072                         DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
   5073                         eRet = OMX_ErrorInvalidState;
   5074                         break;
   5075                     }
   5076                     //set property dynamic buffer mode to driver.
   5077                     struct v4l2_control control;
   5078                     struct v4l2_format fmt;
   5079                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   5080                     if (metabuffer->bStoreMetaData == true) {
   5081                         control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   5082                     } else {
   5083                         control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
   5084                     }
   5085                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   5086                     if (!rc) {
   5087                         DEBUG_PRINT_HIGH("%s buffer mode",
   5088                            (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
   5089                                dynamic_buf_mode = metabuffer->bStoreMetaData;
   5090                     } else {
   5091                         DEBUG_PRINT_ERROR("Failed to %s buffer mode",
   5092                            (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
   5093                         eRet = OMX_ErrorUnsupportedSetting;
   5094                     }
   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;
   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         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
   6746                 drv_ctx.ip_buf.actualcount,
   6747                 (unsigned int)drv_ctx.ip_buf.buffer_size);
   6748 
   6749         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   6750                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   6751 
   6752         if (m_inp_mem_ptr == NULL) {
   6753             return OMX_ErrorInsufficientResources;
   6754         }
   6755 
   6756         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   6757                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   6758 
   6759         if (drv_ctx.ptr_inputbuffer == NULL) {
   6760             return OMX_ErrorInsufficientResources;
   6761         }
   6762 #ifdef USE_ION
   6763         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   6764                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   6765 
   6766         if (drv_ctx.ip_buf_ion_info == NULL) {
   6767             return OMX_ErrorInsufficientResources;
   6768         }
   6769 #endif
   6770 
   6771         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   6772             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   6773 #ifdef USE_ION
   6774             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   6775 #endif
   6776         }
   6777     }
   6778 
   6779     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6780         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6781             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6782             break;
   6783         }
   6784     }
   6785 
   6786     if (i < drv_ctx.ip_buf.actualcount) {
   6787         struct v4l2_buffer buf;
   6788         struct v4l2_plane plane;
   6789         int rc;
   6790         DEBUG_PRINT_LOW("Allocate input Buffer");
   6791 #ifdef USE_ION
   6792         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   6793                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   6794                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   6795                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
   6796                 SECURE_FLAGS_INPUT_BUFFER : 0);
   6797         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   6798             return OMX_ErrorInsufficientResources;
   6799         }
   6800         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   6801 #else
   6802         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6803 
   6804         if (pmem_fd < 0) {
   6805             DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6806             return OMX_ErrorInsufficientResources;
   6807         }
   6808 
   6809         if (pmem_fd == 0) {
   6810             pmem_fd = open (MEM_DEVICE,O_RDWR);
   6811 
   6812             if (pmem_fd < 0) {
   6813                 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6814                 return OMX_ErrorInsufficientResources;
   6815             }
   6816         }
   6817 
   6818         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   6819                     drv_ctx.ip_buf.alignment)) {
   6820             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6821             close(pmem_fd);
   6822             return OMX_ErrorInsufficientResources;
   6823         }
   6824 #endif
   6825         if (!secure_mode) {
   6826             buf_addr = (unsigned char *)mmap(NULL,
   6827                     drv_ctx.ip_buf.buffer_size,
   6828                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   6829 
   6830             if (buf_addr == MAP_FAILED) {
   6831                 close(pmem_fd);
   6832 #ifdef USE_ION
   6833                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   6834 #endif
   6835                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
   6836                 return OMX_ErrorInsufficientResources;
   6837             }
   6838         }
   6839         *bufferHdr = (m_inp_mem_ptr + i);
   6840         if (secure_mode)
   6841             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   6842         else
   6843             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   6844         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   6845         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   6846         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   6847         drv_ctx.ptr_inputbuffer [i].offset = 0;
   6848 
   6849 
   6850         buf.index = i;
   6851         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6852         buf.memory = V4L2_MEMORY_USERPTR;
   6853         plane.bytesused = 0;
   6854         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   6855         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   6856         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   6857         plane.reserved[1] = 0;
   6858         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   6859         buf.m.planes = &plane;
   6860         buf.length = 1;
   6861 
   6862         DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
   6863                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   6864 
   6865         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6866 
   6867         if (rc) {
   6868             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   6869             /*TODO: How to handle this case */
   6870             return OMX_ErrorInsufficientResources;
   6871         }
   6872 
   6873         input = *bufferHdr;
   6874         BITMASK_SET(&m_inp_bm_count,i);
   6875         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
   6876         if (allocate_native_handle) {
   6877             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
   6878             if (!nh) {
   6879                 DEBUG_PRINT_ERROR("Native handle create failed");
   6880                 return OMX_ErrorInsufficientResources;
   6881             }
   6882             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6883             input->pBuffer = (OMX_U8 *)nh;
   6884         } else if (secure_mode || m_input_pass_buffer_fd) {
   6885             /*Legacy method, pass ion fd stashed directly in pBuffer*/
   6886             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6887         } else {
   6888             input->pBuffer           = (OMX_U8 *)buf_addr;
   6889         }
   6890         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6891         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6892         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6893         input->pAppPrivate       = appData;
   6894         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6895         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   6896 
   6897         if (drv_ctx.disable_dmx) {
   6898             eRet = allocate_desc_buffer(i);
   6899         }
   6900     } else {
   6901         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   6902         eRet = OMX_ErrorInsufficientResources;
   6903     }
   6904     return eRet;
   6905 }
   6906 
   6907 
   6908 /* ======================================================================
   6909    FUNCTION
   6910    omx_vdec::AllocateOutputBuffer
   6911 
   6912    DESCRIPTION
   6913    Helper fn for AllocateBuffer in the output pin
   6914 
   6915    PARAMETERS
   6916    <TBD>.
   6917 
   6918    RETURN VALUE
   6919    OMX Error None if everything went well.
   6920 
   6921    ========================================================================== */
   6922 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   6923         OMX_IN OMX_HANDLETYPE            hComp,
   6924         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6925         OMX_IN OMX_U32                   port,
   6926         OMX_IN OMX_PTR                   appData,
   6927         OMX_IN OMX_U32                   bytes)
   6928 {
   6929     (void)hComp;
   6930     (void)port;
   6931     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6932     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   6933     unsigned                         i= 0; // Temporary counter
   6934     struct vdec_setbuffer_cmd setbuffers;
   6935     int extra_idx = 0;
   6936 #ifdef USE_ION
   6937     int ion_device_fd =-1;
   6938     struct ion_allocation_data ion_alloc_data;
   6939     struct ion_fd_data fd_ion_data;
   6940 #endif
   6941     if (!m_out_mem_ptr) {
   6942         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
   6943                 drv_ctx.op_buf.actualcount,
   6944                 (unsigned int)drv_ctx.op_buf.buffer_size);
   6945         int nBufHdrSize        = 0;
   6946         int nPlatformEntrySize = 0;
   6947         int nPlatformListSize  = 0;
   6948         int nPMEMInfoSize = 0;
   6949 
   6950         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   6951         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   6952         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   6953 
   6954         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
   6955                 drv_ctx.op_buf.actualcount);
   6956         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   6957             sizeof(OMX_BUFFERHEADERTYPE);
   6958 
   6959         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   6960             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   6961         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   6962             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   6963         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   6964             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   6965 
   6966         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   6967                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   6968                 nPMEMInfoSize,
   6969                 nPlatformListSize);
   6970         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
   6971                 drv_ctx.op_buf.actualcount);
   6972         unsigned char *pmem_baseaddress_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {NULL};
   6973         int pmem_fd[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {-1};
   6974         int alloc_size[MAX_NUM_INPUT_OUTPUT_BUFFERS] = {0};
   6975         static const int block_max_size = 128 * 1024 * 1024;
   6976         unsigned int block_buf_count = block_max_size / drv_ctx.op_buf.buffer_size;
   6977         unsigned int last_block_buf_count = 0, block_count = 1;
   6978         if (drv_ctx.op_buf.actualcount <= block_buf_count) {
   6979             block_buf_count = drv_ctx.op_buf.actualcount;
   6980         } else {
   6981             last_block_buf_count = drv_ctx.op_buf.actualcount % block_buf_count;
   6982             block_count = (drv_ctx.op_buf.actualcount + block_buf_count - 1) / block_buf_count;
   6983         }
   6984         unsigned int idx = 0;
   6985         DEBUG_PRINT_LOW("block_count = %d block_buf_count = %d last_block_buf_count = %d",
   6986             block_count, block_buf_count, last_block_buf_count);
   6987 #ifdef USE_ION
   6988         struct vdec_ion op_buf_ion_info_temp[MAX_NUM_INPUT_OUTPUT_BUFFERS];
   6989         int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
   6990         for (; idx < block_count; idx++) {
   6991             int cnt = ((idx == block_count - 1) && last_block_buf_count) ?
   6992                 last_block_buf_count : block_buf_count;
   6993             alloc_size[idx] = drv_ctx.op_buf.buffer_size * cnt;
   6994             // Allocate output buffers as cached to improve performance of software-reading
   6995             // of the YUVs. Output buffers are cache-invalidated in driver.
   6996             // If color-conversion is involved, Only the C2D output buffers are cached, no
   6997             // need to cache the decoder's output buffers
   6998             op_buf_ion_info_temp[idx].ion_device_fd = alloc_map_ion_memory(
   6999                     alloc_size[idx],
   7000                     secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
   7001                     &op_buf_ion_info_temp[idx].ion_alloc_data, &op_buf_ion_info_temp[idx].fd_ion_data,
   7002                     (secure_mode && !secure_scaling_to_non_secure_opb) ?
   7003                     SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
   7004             if (op_buf_ion_info_temp[idx].ion_device_fd < 0) {
   7005                 DEBUG_PRINT_LOW("Failed to allocate chunk %ul size = %d", idx, alloc_size[idx]);
   7006                 break;
   7007             }
   7008             pmem_fd[idx] = op_buf_ion_info_temp[idx].fd_ion_data.fd;
   7009             DEBUG_PRINT_LOW("Allocated chunk %ul fd = %ul size = %d", idx, pmem_fd[idx], alloc_size[idx]);
   7010         }
   7011         if (idx != block_count) {
   7012             for (OMX_U32 i = 0; i < idx; i++) {
   7013                 close(pmem_fd[i]);
   7014                 free_ion_memory(&op_buf_ion_info_temp[i]);
   7015             }
   7016             return OMX_ErrorInsufficientResources;
   7017         }
   7018 
   7019 #else
   7020         for (idx = 0; idx < block_count; idx++) {
   7021             pmem_fd[idx] = open (MEM_DEVICE,O_RDWR);
   7022 
   7023             if (pmem_fd[idx] < 0) {
   7024                 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   7025                         drv_ctx.op_buf.buffer_size);
   7026                 break;
   7027             }
   7028             int cnt = ((idx == block_count - 1) && last_block_buf_count) ?
   7029                 last_block_buf_count : block_buf_count;
   7030             if (!align_pmem_buffers(pmem_fd[idx], drv_ctx.op_buf.buffer_size * cnt,
   7031                         drv_ctx.op_buf.alignment)) {
   7032                 DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   7033                 close(pmem_fd[idx]);
   7034                 break;
   7035             }
   7036         }
   7037         if (idx != block_count) {
   7038             for (i = 0; i < idx; i++) {
   7039                 close(pmem_fd[i]);
   7040             }
   7041             return OMX_ErrorInsufficientResources;
   7042         }
   7043 #endif
   7044         if (!secure_mode) {
   7045             idx = 0;
   7046             for (; idx < block_count; idx++) {
   7047                 pmem_baseaddress_temp[idx] = (unsigned char *)mmap(NULL,
   7048                         alloc_size[idx],
   7049                         PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd[idx], 0);
   7050 
   7051                 if (pmem_baseaddress_temp[idx] == MAP_FAILED) {
   7052                     DEBUG_PRINT_ERROR("MMAP failed for Size %u for fd = %d",
   7053                             (unsigned int)alloc_size[idx], pmem_fd[idx]);
   7054                     close(pmem_fd[idx]);
   7055 #ifdef USE_ION
   7056                     free_ion_memory(&op_buf_ion_info_temp[idx]);
   7057 #endif
   7058                     break;
   7059                 }
   7060             }
   7061             if (idx != block_count) {
   7062                 for (i = 0; i < idx; i++) {
   7063                     munmap(pmem_baseaddress_temp[idx], alloc_size[idx]);
   7064                     close(pmem_fd[i]);
   7065 #ifdef USE_ION
   7066                     free_ion_memory(&op_buf_ion_info_temp[i]);
   7067 #endif
   7068                 }
   7069                 return OMX_ErrorInsufficientResources;
   7070             }
   7071         }
   7072         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   7073         // Alloc mem for platform specific info
   7074         char *pPtr=NULL;
   7075         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   7076                 nPMEMInfoSize,1);
   7077         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   7078                        calloc (sizeof(struct vdec_bufferpayload),
   7079                                drv_ctx.op_buf.actualcount);
   7080         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   7081                      calloc (sizeof (struct vdec_output_frameinfo),
   7082                              drv_ctx.op_buf.actualcount);
   7083         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   7084             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
   7085             return OMX_ErrorInsufficientResources;
   7086         }
   7087 
   7088 #ifdef USE_ION
   7089         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   7090                       calloc (sizeof(struct vdec_ion),
   7091                               drv_ctx.op_buf.actualcount);
   7092         if (!drv_ctx.op_buf_ion_info) {
   7093             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   7094             return OMX_ErrorInsufficientResources;
   7095         }
   7096 #endif
   7097         drv_ctx.op_buf_map_info = (struct vdec_ion_map_info *)\
   7098                       calloc (sizeof(struct vdec_ion_map_info),
   7099                               drv_ctx.op_buf.actualcount);
   7100         if (!drv_ctx.op_buf_map_info) {
   7101             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_map_info");
   7102             return OMX_ErrorInsufficientResources;
   7103         }
   7104 
   7105         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   7106                 && drv_ctx.ptr_respbuffer) {
   7107             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   7108                 (drv_ctx.op_buf.buffer_size *
   7109                  drv_ctx.op_buf.actualcount);
   7110             bufHdr          =  m_out_mem_ptr;
   7111             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   7112             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   7113                 (((char *) m_platform_list)  + nPlatformListSize);
   7114             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   7115                 (((char *) m_platform_entry) + nPlatformEntrySize);
   7116             pPlatformList   = m_platform_list;
   7117             pPlatformEntry  = m_platform_entry;
   7118             pPMEMInfo       = m_pmem_info;
   7119 
   7120             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   7121 
   7122             // Settting the entire storage nicely
   7123             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
   7124             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   7125             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   7126                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   7127                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   7128                 // Set the values when we determine the right HxW param
   7129                 bufHdr->nAllocLen          = bytes;
   7130                 bufHdr->nFilledLen         = 0;
   7131                 bufHdr->pAppPrivate        = appData;
   7132                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   7133                 // Platform specific PMEM Information
   7134                 // Initialize the Platform Entry
   7135                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
   7136                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   7137                 pPlatformEntry->entry      = pPMEMInfo;
   7138                 // Initialize the Platform List
   7139                 pPlatformList->nEntries    = 1;
   7140                 pPlatformList->entryList   = pPlatformEntry;
   7141                 // Keep pBuffer NULL till vdec is opened
   7142                 bufHdr->pBuffer            = NULL;
   7143                 bufHdr->nOffset            = 0;
   7144 
   7145                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   7146                 pPMEMInfo->pmem_fd = -1;
   7147                 bufHdr->pPlatformPrivate = pPlatformList;
   7148 
   7149                 int block_idx = i / block_buf_count;
   7150                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd[block_idx];
   7151                 m_pmem_info[i].pmem_fd = pmem_fd[block_idx];
   7152 #ifdef USE_ION
   7153                 drv_ctx.op_buf_ion_info[i].ion_device_fd = op_buf_ion_info_temp[block_idx].ion_device_fd;
   7154                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = op_buf_ion_info_temp[block_idx].ion_alloc_data;
   7155                 drv_ctx.op_buf_ion_info[i].fd_ion_data = op_buf_ion_info_temp[block_idx].fd_ion_data;
   7156 #endif
   7157                 drv_ctx.op_buf_map_info[i].free_buffer = !(i % block_buf_count);
   7158                 drv_ctx.op_buf_map_info[i].base_address = pmem_baseaddress_temp[block_idx];
   7159                 drv_ctx.op_buf_map_info[i].map_size = alloc_size[block_idx];
   7160                 drv_ctx.op_buf_map_info[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count);
   7161 
   7162                 /*Create a mapping between buffers*/
   7163                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   7164                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   7165                                     &drv_ctx.ptr_outputbuffer[i];
   7166                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size * (i % block_buf_count);
   7167                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   7168                     pmem_baseaddress_temp[block_idx] + (drv_ctx.op_buf.buffer_size * (i % block_buf_count));
   7169                 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   7170                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   7171                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   7172 
   7173                 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
   7174                         pmem_fd[block_idx], (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
   7175                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   7176                 // Move the buffer and buffer header pointers
   7177                 bufHdr++;
   7178                 pPMEMInfo++;
   7179                 pPlatformEntry++;
   7180                 pPlatformList++;
   7181             }
   7182         } else {
   7183             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   7184                     m_out_mem_ptr, pPtr);
   7185             if (m_out_mem_ptr) {
   7186                 free(m_out_mem_ptr);
   7187                 m_out_mem_ptr = NULL;
   7188             }
   7189             if (pPtr) {
   7190                 free(pPtr);
   7191                 pPtr = NULL;
   7192             }
   7193             if (drv_ctx.ptr_outputbuffer) {
   7194                 free(drv_ctx.ptr_outputbuffer);
   7195                 drv_ctx.ptr_outputbuffer = NULL;
   7196             }
   7197             if (drv_ctx.ptr_respbuffer) {
   7198                 free(drv_ctx.ptr_respbuffer);
   7199                 drv_ctx.ptr_respbuffer = NULL;
   7200             }
   7201 #ifdef USE_ION
   7202             if (drv_ctx.op_buf_ion_info) {
   7203                 DEBUG_PRINT_LOW("Free o/p ion context");
   7204                 free(drv_ctx.op_buf_ion_info);
   7205                 drv_ctx.op_buf_ion_info = NULL;
   7206             }
   7207 #endif
   7208             free(drv_ctx.op_buf_map_info);
   7209             drv_ctx.op_buf_map_info = NULL;
   7210            eRet =  OMX_ErrorInsufficientResources;
   7211         }
   7212         if (eRet == OMX_ErrorNone)
   7213             eRet = allocate_extradata();
   7214     }
   7215 
   7216     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   7217         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   7218             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   7219             break;
   7220         }
   7221     }
   7222 
   7223     if (eRet == OMX_ErrorNone) {
   7224         if (i < drv_ctx.op_buf.actualcount) {
   7225             struct v4l2_buffer buf;
   7226             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   7227             int rc;
   7228             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   7229 
   7230             drv_ctx.ptr_outputbuffer[i].buffer_len =
   7231                 drv_ctx.op_buf.buffer_size;
   7232 
   7233             *bufferHdr = (m_out_mem_ptr + i );
   7234             if (secure_mode) {
   7235 #ifdef USE_ION
   7236                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   7237                     (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   7238 #else
   7239                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   7240 #endif
   7241             }
   7242             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   7243 
   7244             buf.index = i;
   7245             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7246             buf.memory = V4L2_MEMORY_USERPTR;
   7247             plane[0].length = drv_ctx.op_buf.buffer_size;
   7248             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   7249                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   7250 #ifdef USE_ION
   7251             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   7252 #endif
   7253             plane[0].reserved[1] = drv_ctx.op_buf_map_info[i].offset;
   7254             plane[0].data_offset = 0;
   7255             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   7256             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   7257                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   7258                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   7259 #ifdef USE_ION
   7260                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   7261 #endif
   7262                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   7263                 plane[extra_idx].data_offset = 0;
   7264             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   7265                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
   7266                 return OMX_ErrorBadParameter;
   7267             }
   7268             buf.m.planes = plane;
   7269             buf.length = drv_ctx.num_planes;
   7270             DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   7271             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   7272             if (rc) {
   7273                 /*TODO: How to handle this case */
   7274                 return OMX_ErrorInsufficientResources;
   7275             }
   7276 
   7277             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   7278                 enum v4l2_buf_type buf_type;
   7279                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7280                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7281                 if (rc) {
   7282                     return OMX_ErrorInsufficientResources;
   7283                 } else {
   7284                     streaming[CAPTURE_PORT] = true;
   7285                     DEBUG_PRINT_LOW("STREAMON Successful");
   7286                 }
   7287 
   7288                 DEBUG_PRINT_HIGH("Enabling Turbo mode");
   7289                 request_perf_level(VIDC_TURBO);
   7290             }
   7291 
   7292             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   7293             (*bufferHdr)->pAppPrivate = appData;
   7294             BITMASK_SET(&m_out_bm_count,i);
   7295         } else {
   7296             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
   7297             eRet = OMX_ErrorInsufficientResources;
   7298         }
   7299     }
   7300 
   7301     return eRet;
   7302 }
   7303 
   7304 
   7305 // AllocateBuffer  -- API Call
   7306 /* ======================================================================
   7307    FUNCTION
   7308    omx_vdec::AllocateBuffer
   7309 
   7310    DESCRIPTION
   7311    Returns zero if all the buffers released..
   7312 
   7313    PARAMETERS
   7314    None.
   7315 
   7316    RETURN VALUE
   7317    true/false
   7318 
   7319    ========================================================================== */
   7320 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   7321         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   7322         OMX_IN OMX_U32                        port,
   7323         OMX_IN OMX_PTR                     appData,
   7324         OMX_IN OMX_U32                       bytes)
   7325 {
   7326     unsigned i = 0;
   7327     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   7328 
   7329     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
   7330     if (m_state == OMX_StateInvalid) {
   7331         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
   7332         return OMX_ErrorInvalidState;
   7333     }
   7334 
   7335     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   7336         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
   7337         // ensure that use-buffer was never called.
   7338         // Mix-and-match of useBuffer and allocateBuffer is not allowed
   7339         if (m_inp_mem_ptr && input_use_buffer) {
   7340             DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
   7341             return OMX_ErrorUndefined;
   7342         }
   7343         if (arbitrary_bytes) {
   7344             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   7345         } else {
   7346             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   7347         }
   7348     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   7349         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   7350                 appData,bytes);
   7351     } else {
   7352         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   7353         eRet = OMX_ErrorBadPortIndex;
   7354     }
   7355     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   7356     if (eRet == OMX_ErrorNone) {
   7357         if (allocate_done()) {
   7358             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   7359                 // Send the callback now
   7360                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   7361                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   7362                         OMX_COMPONENT_GENERATE_EVENT);
   7363             }
   7364         }
   7365         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   7366             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   7367                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   7368                 post_event(OMX_CommandPortEnable,
   7369                         OMX_CORE_INPUT_PORT_INDEX,
   7370                         OMX_COMPONENT_GENERATE_EVENT);
   7371             }
   7372         }
   7373         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   7374             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   7375                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   7376                 post_event(OMX_CommandPortEnable,
   7377                         OMX_CORE_OUTPUT_PORT_INDEX,
   7378                         OMX_COMPONENT_GENERATE_EVENT);
   7379             }
   7380         }
   7381     }
   7382     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   7383     return eRet;
   7384 }
   7385 
   7386 // Free Buffer - API call
   7387 /* ======================================================================
   7388    FUNCTION
   7389    omx_vdec::FreeBuffer
   7390 
   7391    DESCRIPTION
   7392 
   7393    PARAMETERS
   7394    None.
   7395 
   7396    RETURN VALUE
   7397    true/false
   7398 
   7399    ========================================================================== */
   7400 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   7401         OMX_IN OMX_U32                 port,
   7402         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7403 {
   7404     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7405     unsigned int nPortIndex;
   7406     (void) hComp;
   7407     DEBUG_PRINT_LOW("In for decoder free_buffer");
   7408 
   7409     if (m_state == OMX_StateIdle &&
   7410             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   7411         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   7412     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   7413             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   7414         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   7415     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   7416                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   7417             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   7418              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   7419         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
   7420     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   7421         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
   7422         post_event(OMX_EventError,
   7423                 OMX_ErrorPortUnpopulated,
   7424                 OMX_COMPONENT_GENERATE_EVENT);
   7425 
   7426         return OMX_ErrorIncorrectStateOperation;
   7427     } else if (m_state != OMX_StateInvalid) {
   7428         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
   7429         post_event(OMX_EventError,
   7430                 OMX_ErrorPortUnpopulated,
   7431                 OMX_COMPONENT_GENERATE_EVENT);
   7432     }
   7433 
   7434     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   7435         /*Check if arbitrary bytes*/
   7436         if (!arbitrary_bytes && !input_use_buffer)
   7437             nPortIndex = buffer - m_inp_mem_ptr;
   7438         else
   7439             nPortIndex = buffer - m_inp_heap_ptr;
   7440 
   7441         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
   7442         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
   7443                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   7444             // Clear the bit associated with it.
   7445             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   7446             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   7447             if (input_use_buffer == true) {
   7448 
   7449                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
   7450                 if (m_phdr_pmem_ptr)
   7451                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   7452             } else {
   7453                 if (arbitrary_bytes) {
   7454                     if (m_phdr_pmem_ptr)
   7455                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   7456                     else
   7457                         free_input_buffer(nPortIndex,NULL);
   7458                 } else
   7459                     free_input_buffer(buffer);
   7460             }
   7461             m_inp_bPopulated = OMX_FALSE;
   7462             if(release_input_done())
   7463                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   7464             /*Free the Buffer Header*/
   7465             if (release_input_done()) {
   7466                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
   7467                 free_input_buffer_header();
   7468             }
   7469         } else {
   7470             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
   7471             eRet = OMX_ErrorBadPortIndex;
   7472         }
   7473 
   7474         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   7475                 && release_input_done()) {
   7476             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   7477             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   7478             post_event(OMX_CommandPortDisable,
   7479                     OMX_CORE_INPUT_PORT_INDEX,
   7480                     OMX_COMPONENT_GENERATE_EVENT);
   7481         }
   7482     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   7483         // check if the buffer is valid
   7484         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7485         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7486                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   7487             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
   7488             // Clear the bit associated with it.
   7489             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   7490             m_out_bPopulated = OMX_FALSE;
   7491             client_buffers.free_output_buffer (buffer);
   7492 
   7493             if(release_output_done()) {
   7494                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   7495             }
   7496             if (release_output_done()) {
   7497                 free_output_buffer_header();
   7498             }
   7499         } else {
   7500             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
   7501             eRet = OMX_ErrorBadPortIndex;
   7502         }
   7503         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   7504                 && release_output_done()) {
   7505             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   7506 
   7507             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   7508             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   7509 #ifdef _ANDROID_ICS_
   7510             if (m_enable_android_native_buffers) {
   7511                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   7512                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   7513             }
   7514 #endif
   7515 
   7516             post_event(OMX_CommandPortDisable,
   7517                     OMX_CORE_OUTPUT_PORT_INDEX,
   7518                     OMX_COMPONENT_GENERATE_EVENT);
   7519         }
   7520     } else if (port == OMX_CORE_OUTPUT_EXTRADATA_INDEX) {
   7521         nPortIndex = buffer - m_client_output_extradata_mem_ptr;
   7522         DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
   7523 
   7524         BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
   7525 
   7526         if (release_output_extradata_done()) {
   7527             free_output_extradata_buffer_header();
   7528         }
   7529     } else {
   7530         eRet = OMX_ErrorBadPortIndex;
   7531     }
   7532     if ((eRet == OMX_ErrorNone) &&
   7533             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   7534         if (release_done()) {
   7535             /*
   7536              * Reset buffer requirements here to ensure setting buffer requirement
   7537              * when component move to executing state from loaded state via idle.
   7538              */
   7539             drv_ctx.op_buf.buffer_size = 0;
   7540             drv_ctx.op_buf.actualcount = 0;
   7541 
   7542             // Send the callback now
   7543             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   7544             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   7545                     OMX_COMPONENT_GENERATE_EVENT);
   7546         }
   7547     }
   7548     return eRet;
   7549 }
   7550 
   7551 
   7552 /* ======================================================================
   7553    FUNCTION
   7554    omx_vdec::EmptyThisBuffer
   7555 
   7556    DESCRIPTION
   7557    This routine is used to push the encoded video frames to
   7558    the video decoder.
   7559 
   7560    PARAMETERS
   7561    None.
   7562 
   7563    RETURN VALUE
   7564    OMX Error None if everything went successful.
   7565 
   7566    ========================================================================== */
   7567 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   7568         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7569 {
   7570     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   7571     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   7572 
   7573     if (m_state != OMX_StateExecuting &&
   7574             m_state != OMX_StatePause &&
   7575             m_state != OMX_StateIdle) {
   7576         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
   7577         return OMX_ErrorInvalidState;
   7578     }
   7579 
   7580     if (buffer == NULL) {
   7581         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   7582         return OMX_ErrorBadParameter;
   7583     }
   7584 
   7585     if (!m_inp_bEnabled) {
   7586         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   7587         return OMX_ErrorIncorrectStateOperation;
   7588     }
   7589 
   7590     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   7591         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
   7592         return OMX_ErrorBadPortIndex;
   7593     }
   7594 
   7595     if (perf_flag) {
   7596         if (!latency) {
   7597             dec_time.stop();
   7598             latency = dec_time.processing_time_us();
   7599             dec_time.start();
   7600         }
   7601     }
   7602 
   7603     if (arbitrary_bytes) {
   7604         nBufferIndex = buffer - m_inp_heap_ptr;
   7605     } else {
   7606         if (input_use_buffer == true) {
   7607             nBufferIndex = buffer - m_inp_heap_ptr;
   7608             if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7609                 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
   7610                 return OMX_ErrorBadParameter;
   7611             }
   7612             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   7613             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   7614             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   7615             buffer = &m_inp_mem_ptr[nBufferIndex];
   7616             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
   7617                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
   7618         } else {
   7619             nBufferIndex = buffer - m_inp_mem_ptr;
   7620         }
   7621     }
   7622 
   7623     if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7624         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   7625         return OMX_ErrorBadParameter;
   7626     }
   7627 
   7628     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7629         codec_config_flag = true;
   7630         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   7631     }
   7632 
   7633     /* The client should not set this when codec is in arbitrary bytes mode */
   7634     if (m_input_pass_buffer_fd) {
   7635         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
   7636     }
   7637 
   7638     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
   7639             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
   7640     if (arbitrary_bytes) {
   7641         post_event ((unsigned long)hComp,(unsigned long)buffer,
   7642                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   7643     } else {
   7644         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
   7645     }
   7646     time_stamp_dts.insert_timestamp(buffer);
   7647     return OMX_ErrorNone;
   7648 }
   7649 
   7650 /* ======================================================================
   7651    FUNCTION
   7652    omx_vdec::empty_this_buffer_proxy
   7653 
   7654    DESCRIPTION
   7655    This routine is used to push the encoded video frames to
   7656    the video decoder.
   7657 
   7658    PARAMETERS
   7659    None.
   7660 
   7661    RETURN VALUE
   7662    OMX Error None if everything went successful.
   7663 
   7664    ========================================================================== */
   7665 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   7666         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7667 {
   7668     VIDC_TRACE_NAME_HIGH("ETB");
   7669     (void) hComp;
   7670     int push_cnt = 0,i=0;
   7671     unsigned nPortIndex = 0;
   7672     OMX_ERRORTYPE ret = OMX_ErrorNone;
   7673     struct vdec_input_frameinfo frameinfo;
   7674     struct vdec_bufferpayload *temp_buffer;
   7675     struct vdec_seqheader seq_header;
   7676     bool port_setting_changed = true;
   7677 
   7678     /*Should we generate a Aync error event*/
   7679     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   7680         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   7681         return OMX_ErrorBadParameter;
   7682     }
   7683 
   7684     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   7685 
   7686     if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
   7687         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   7688                 nPortIndex);
   7689         return OMX_ErrorBadParameter;
   7690     }
   7691 
   7692     pending_input_buffers++;
   7693     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   7694 
   7695     /* return zero length and not an EOS buffer */
   7696     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   7697             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   7698         DEBUG_PRINT_HIGH("return zero legth buffer");
   7699         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7700                 OMX_COMPONENT_GENERATE_EBD);
   7701         return OMX_ErrorNone;
   7702     }
   7703 
   7704     if (input_flush_progress == true) {
   7705         DEBUG_PRINT_LOW("Flush in progress return buffer ");
   7706         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7707                 OMX_COMPONENT_GENERATE_EBD);
   7708         return OMX_ErrorNone;
   7709     }
   7710 
   7711     auto_lock l(buf_lock);
   7712     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   7713 
   7714     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
   7715         return OMX_ErrorBadParameter;
   7716     }
   7717     /* If its first frame, H264 codec and reject is true, then parse the nal
   7718        and get the profile. Based on this, reject the clip playback */
   7719     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   7720             m_reject_avc_1080p_mp) {
   7721         first_frame = 1;
   7722         DEBUG_PRINT_ERROR("Parse nal to get the profile");
   7723         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   7724                 NALU_TYPE_SPS);
   7725         m_profile = h264_parser->get_profile();
   7726         ret = is_video_session_supported();
   7727         if (ret) {
   7728             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   7729             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   7730             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   7731             m_state = OMX_StateInvalid;
   7732             return OMX_ErrorNone;
   7733         }
   7734     }
   7735 
   7736     VIDC_TRACE_INT_LOW("ETB-TS", buffer->nTimeStamp / 1000);
   7737     VIDC_TRACE_INT_LOW("ETB-size", buffer->nFilledLen);
   7738     DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7739     /*for use buffer we need to memcpy the data*/
   7740     temp_buffer->buffer_len = buffer->nFilledLen;
   7741 
   7742     if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
   7743         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   7744             if (arbitrary_bytes) {
   7745                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   7746             } else {
   7747                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   7748                         buffer->nFilledLen);
   7749             }
   7750         } else {
   7751             return OMX_ErrorBadParameter;
   7752         }
   7753 
   7754     }
   7755 
   7756     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   7757     frameinfo.client_data = (void *) buffer;
   7758     frameinfo.datalen = temp_buffer->buffer_len;
   7759     frameinfo.flags = 0;
   7760     frameinfo.offset = buffer->nOffset;
   7761     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   7762     frameinfo.pmem_offset = temp_buffer->offset;
   7763     frameinfo.timestamp = buffer->nTimeStamp;
   7764     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   7765         DEBUG_PRINT_LOW("ETB: dmx enabled");
   7766         if (m_demux_entries == 0) {
   7767             extract_demux_addr_offsets(buffer);
   7768         }
   7769 
   7770         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
   7771         handle_demux_data(buffer);
   7772         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   7773         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   7774     } else {
   7775         frameinfo.desc_addr = NULL;
   7776         frameinfo.desc_size = 0;
   7777     }
   7778     if (!arbitrary_bytes) {
   7779         frameinfo.flags |= buffer->nFlags;
   7780     }
   7781 
   7782 #ifdef _ANDROID_
   7783     if (m_debug_timestamp) {
   7784         if (arbitrary_bytes) {
   7785             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7786             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7787         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7788             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7789             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7790         }
   7791     }
   7792 #endif
   7793 
   7794     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
   7795 
   7796 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7797         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7798         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7799     }
   7800 
   7801     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7802         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
   7803         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   7804         h264_scratch.nFilledLen = 0;
   7805         nal_count = 0;
   7806         look_ahead_nal = false;
   7807         frame_count = 0;
   7808         if (m_frame_parser.mutils)
   7809             m_frame_parser.mutils->initialize_frame_checking_environment();
   7810         m_frame_parser.flush();
   7811         h264_last_au_ts = LLONG_MAX;
   7812         h264_last_au_flags = 0;
   7813         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   7814         m_demux_entries = 0;
   7815     }
   7816     struct v4l2_buffer buf;
   7817     struct v4l2_plane plane;
   7818     memset( (void *)&buf, 0, sizeof(buf));
   7819     memset( (void *)&plane, 0, sizeof(plane));
   7820     int rc;
   7821     unsigned long  print_count;
   7822     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7823         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   7824         DEBUG_PRINT_HIGH("INPUT EOS reached") ;
   7825     }
   7826     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7827     buf.index = nPortIndex;
   7828     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7829     buf.memory = V4L2_MEMORY_USERPTR;
   7830     plane.bytesused = temp_buffer->buffer_len;
   7831     plane.length = drv_ctx.ip_buf.buffer_size;
   7832     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   7833         (unsigned long)temp_buffer->offset;
   7834     plane.reserved[0] = temp_buffer->pmem_fd;
   7835     plane.reserved[1] = temp_buffer->offset;
   7836     plane.data_offset = 0;
   7837     buf.m.planes = &plane;
   7838     buf.length = 1;
   7839     if (frameinfo.timestamp >= LLONG_MAX) {
   7840         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   7841     }
   7842     //assumption is that timestamp is in milliseconds
   7843     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   7844     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   7845     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   7846     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   7847 
   7848     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7849         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
   7850         android_atomic_inc(&m_queued_codec_config_count);
   7851     }
   7852 
   7853     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7854     if (rc) {
   7855         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver, send ETB back to client");
   7856         m_cb.EmptyBufferDone(hComp, m_app_data, buffer);
   7857         return OMX_ErrorHardware;
   7858     }
   7859 
   7860     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7861         codec_config_flag = false;
   7862     }
   7863     if (!streaming[OUTPUT_PORT]) {
   7864         enum v4l2_buf_type buf_type;
   7865         int ret,r;
   7866 
   7867         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7868         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   7869         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7870         if (!ret) {
   7871             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
   7872             streaming[OUTPUT_PORT] = true;
   7873         } else if (errno == EBUSY) {
   7874             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
   7875             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7876                     OMX_COMPONENT_GENERATE_EBD);
   7877             return OMX_ErrorInsufficientResources;
   7878         } else {
   7879             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
   7880             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   7881             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7882                     OMX_COMPONENT_GENERATE_EBD);
   7883             return OMX_ErrorBadParameter;
   7884         }
   7885     }
   7886     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
   7887             frameinfo.bufferaddr, (long long)frameinfo.timestamp,
   7888             (unsigned int)frameinfo.datalen);
   7889 
   7890     return ret;
   7891 }
   7892 
   7893 /* ======================================================================
   7894    FUNCTION
   7895    omx_vdec::FillThisBuffer
   7896 
   7897    DESCRIPTION
   7898    IL client uses this method to release the frame buffer
   7899    after displaying them.
   7900 
   7901    PARAMETERS
   7902    None.
   7903 
   7904    RETURN VALUE
   7905    true/false
   7906 
   7907    ========================================================================== */
   7908 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   7909         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7910 {
   7911     if (m_state != OMX_StateExecuting &&
   7912             m_state != OMX_StatePause &&
   7913             m_state != OMX_StateIdle) {
   7914         DEBUG_PRINT_ERROR("FTB in Invalid State");
   7915         return OMX_ErrorInvalidState;
   7916     }
   7917 
   7918     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   7919         DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
   7920         return OMX_ErrorBadPortIndex;
   7921     }
   7922 
   7923     if (!m_out_bEnabled) {
   7924         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   7925         return OMX_ErrorIncorrectStateOperation;
   7926     }
   7927 
   7928     unsigned nPortIndex = 0;
   7929     if (dynamic_buf_mode) {
   7930         private_handle_t *handle = NULL;
   7931         struct VideoDecoderOutputMetaData *meta;
   7932         unsigned int nPortIndex = 0;
   7933 
   7934         if (!buffer || !buffer->pBuffer) {
   7935             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
   7936             return OMX_ErrorBadParameter;
   7937         }
   7938 
   7939         //get the buffer type and fd info
   7940         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   7941         handle = (private_handle_t *)meta->pHandle;
   7942         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
   7943 
   7944         if (!handle) {
   7945             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
   7946             return OMX_ErrorBadParameter;
   7947         }
   7948         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   7949         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7950         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7951             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   7952             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   7953             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   7954 
   7955            //Store private handle from GraphicBuffer
   7956             native_buffer[nPortIndex].privatehandle = handle;
   7957             native_buffer[nPortIndex].nativehandle = handle;
   7958         } else {
   7959             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
   7960             return OMX_ErrorBadParameter;
   7961         }
   7962 
   7963         //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
   7964         //this with a more sane size so that we don't compensate in rest of code
   7965         //We'll restore this size later on, so that it's transparent to client
   7966         buffer->nFilledLen = 0;
   7967         buffer->nAllocLen = handle->size;
   7968 
   7969         if (handle->flags & private_handle_t::PRIV_FLAGS_DISP_CONSUMER) {
   7970             m_is_display_session = true;
   7971         } else {
   7972             m_is_display_session = false;
   7973         }
   7974         DEBUG_PRINT_LOW("%s: m_is_display_session = %d", __func__, m_is_display_session);
   7975 
   7976         drv_ctx.op_buf.buffer_size = handle->size;
   7977     }
   7978 
   7979     nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7980     if (buffer == NULL ||
   7981             (nPortIndex >= drv_ctx.op_buf.actualcount)) {
   7982         DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7983             nPortIndex, drv_ctx.op_buf.actualcount);
   7984         return OMX_ErrorBadParameter;
   7985     }
   7986 
   7987     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7988     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
   7989     return OMX_ErrorNone;
   7990 }
   7991 /* ======================================================================
   7992    FUNCTION
   7993    omx_vdec::fill_this_buffer_proxy
   7994 
   7995    DESCRIPTION
   7996    IL client uses this method to release the frame buffer
   7997    after displaying them.
   7998 
   7999    PARAMETERS
   8000    None.
   8001 
   8002    RETURN VALUE
   8003    true/false
   8004 
   8005    ========================================================================== */
   8006 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   8007         OMX_IN OMX_HANDLETYPE        hComp,
   8008         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   8009 {
   8010     VIDC_TRACE_NAME_HIGH("FTB");
   8011     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   8012     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   8013     unsigned nPortIndex = 0;
   8014     struct vdec_fillbuffer_cmd fillbuffer;
   8015     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   8016     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   8017 
   8018     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8019 
   8020     if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
   8021         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   8022             nPortIndex, drv_ctx.op_buf.actualcount);
   8023         return OMX_ErrorBadParameter;
   8024     }
   8025 
   8026     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   8027             bufferAdd, bufferAdd->pBuffer);
   8028     /*Return back the output buffer to client*/
   8029     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true || in_reconfig) {
   8030         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
   8031         buffer->nFilledLen = 0;
   8032         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   8033         return OMX_ErrorNone;
   8034     }
   8035 
   8036     if (dynamic_buf_mode) {
   8037         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   8038         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen;
   8039         buf_ref_add(nPortIndex);
   8040         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen;
   8041     }
   8042 
   8043     pending_output_buffers++;
   8044     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8045     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   8046     if (!buffer) {
   8047        DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
   8048        return OMX_ErrorBadParameter;
   8049     }
   8050     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   8051     if (ptr_respbuffer) {
   8052         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   8053     }
   8054 
   8055     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   8056         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   8057         buffer->nFilledLen = 0;
   8058         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   8059         pending_output_buffers--;
   8060         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8061         return OMX_ErrorBadParameter;
   8062     }
   8063 
   8064     int rc = 0;
   8065     struct v4l2_buffer buf;
   8066     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   8067     memset( (void *)&buf, 0, sizeof(buf));
   8068     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   8069     unsigned int extra_idx = 0;
   8070 
   8071     buf.index = nPortIndex;
   8072     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8073     buf.memory = V4L2_MEMORY_USERPTR;
   8074     plane[0].bytesused = buffer->nFilledLen;
   8075     plane[0].length = buffer->nAllocLen;
   8076     plane[0].m.userptr =
   8077         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   8078         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   8079     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   8080     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   8081     plane[0].data_offset = 0;
   8082     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   8083     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   8084         plane[extra_idx].bytesused = 0;
   8085         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   8086         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   8087 #ifdef USE_ION
   8088         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   8089 #endif
   8090         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   8091         plane[extra_idx].data_offset = 0;
   8092     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   8093         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   8094         return OMX_ErrorBadParameter;
   8095     }
   8096     buf.m.planes = plane;
   8097     buf.length = drv_ctx.num_planes;
   8098     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   8099              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress);
   8100 
   8101     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   8102     if (rc) {
   8103         buffer->nFilledLen = 0;
   8104         DEBUG_PRINT_ERROR("Failed to qbuf to driver, error %s", strerror(errno));
   8105         m_cb.FillBufferDone(hComp, m_app_data, buffer);
   8106         return OMX_ErrorHardware;
   8107     }
   8108 
   8109     return OMX_ErrorNone;
   8110 }
   8111 
   8112 /* ======================================================================
   8113    FUNCTION
   8114    omx_vdec::SetCallbacks
   8115 
   8116    DESCRIPTION
   8117    Set the callbacks.
   8118 
   8119    PARAMETERS
   8120    None.
   8121 
   8122    RETURN VALUE
   8123    OMX Error None if everything successful.
   8124 
   8125    ========================================================================== */
   8126 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   8127         OMX_IN OMX_CALLBACKTYPE* callbacks,
   8128         OMX_IN OMX_PTR             appData)
   8129 {
   8130     (void) hComp;
   8131     m_cb       = *callbacks;
   8132     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   8133             m_cb.EventHandler,m_cb.FillBufferDone);
   8134     m_app_data =    appData;
   8135     return OMX_ErrorNotImplemented;
   8136 }
   8137 
   8138 /* ======================================================================
   8139    FUNCTION
   8140    omx_vdec::ComponentDeInit
   8141 
   8142    DESCRIPTION
   8143    Destroys the component and release memory allocated to the heap.
   8144 
   8145    PARAMETERS
   8146    <TBD>.
   8147 
   8148    RETURN VALUE
   8149    OMX Error None if everything successful.
   8150 
   8151    ========================================================================== */
   8152 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   8153 {
   8154    (void) hComp;
   8155 
   8156     unsigned i = 0;
   8157     if (OMX_StateLoaded != m_state) {
   8158         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
   8159                 m_state);
   8160         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   8161     } else {
   8162         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
   8163     }
   8164 
   8165     /*Check if the output buffers have to be cleaned up*/
   8166     if (m_out_mem_ptr) {
   8167         DEBUG_PRINT_LOW("Freeing the Output Memory");
   8168         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   8169             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
   8170                 BITMASK_CLEAR(&m_out_bm_count, i);
   8171                 client_buffers.free_output_buffer (&m_out_mem_ptr[i]);
   8172             }
   8173 
   8174             if (release_output_done()) {
   8175                 break;
   8176             }
   8177         }
   8178 #ifdef _ANDROID_ICS_
   8179         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   8180 #endif
   8181     }
   8182 
   8183     /*Check if the input buffers have to be cleaned up*/
   8184     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   8185         DEBUG_PRINT_LOW("Freeing the Input Memory");
   8186         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   8187 
   8188             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
   8189                 BITMASK_CLEAR(&m_inp_bm_count, i);
   8190                 if (m_inp_mem_ptr)
   8191                     free_input_buffer (i,&m_inp_mem_ptr[i]);
   8192                 else
   8193                     free_input_buffer (i,NULL);
   8194             }
   8195 
   8196             if (release_input_done()) {
   8197                 break;
   8198             }
   8199        }
   8200     }
   8201     free_input_buffer_header();
   8202     free_output_buffer_header();
   8203     if (h264_scratch.pBuffer) {
   8204         free(h264_scratch.pBuffer);
   8205         h264_scratch.pBuffer = NULL;
   8206     }
   8207 
   8208     if (h264_parser) {
   8209         delete h264_parser;
   8210         h264_parser = NULL;
   8211     }
   8212 
   8213     if (m_frame_parser.mutils) {
   8214         DEBUG_PRINT_LOW("Free utils parser");
   8215         delete (m_frame_parser.mutils);
   8216         m_frame_parser.mutils = NULL;
   8217     }
   8218 
   8219     if (m_platform_list) {
   8220         free(m_platform_list);
   8221         m_platform_list = NULL;
   8222     }
   8223     if (m_vendor_config.pData) {
   8224         free(m_vendor_config.pData);
   8225         m_vendor_config.pData = NULL;
   8226     }
   8227 
   8228     // Reset counters in mesg queues
   8229     m_ftb_q.m_size=0;
   8230     m_cmd_q.m_size=0;
   8231     m_etb_q.m_size=0;
   8232     m_ftb_q.m_read = m_ftb_q.m_write =0;
   8233     m_cmd_q.m_read = m_cmd_q.m_write =0;
   8234     m_etb_q.m_read = m_etb_q.m_write =0;
   8235 #ifdef _ANDROID_
   8236     if (m_debug_timestamp) {
   8237         m_timestamp_list.reset_ts_list();
   8238     }
   8239 #endif
   8240 
   8241     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
   8242     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   8243     // NULL);
   8244     DEBUG_PRINT_HIGH("Close the driver instance");
   8245 
   8246     if (m_debug.infile) {
   8247         fclose(m_debug.infile);
   8248         m_debug.infile = NULL;
   8249     }
   8250     if (m_debug.outfile) {
   8251         fclose(m_debug.outfile);
   8252         m_debug.outfile = NULL;
   8253     }
   8254     if (m_debug.out_ymeta_file) {
   8255         fclose(m_debug.out_ymeta_file);
   8256         m_debug.out_ymeta_file = NULL;
   8257     }
   8258     if (m_debug.out_uvmeta_file) {
   8259         fclose(m_debug.out_uvmeta_file);
   8260         m_debug.out_uvmeta_file = NULL;
   8261     }
   8262 #ifdef OUTPUT_EXTRADATA_LOG
   8263     if (outputExtradataFile)
   8264         fclose (outputExtradataFile);
   8265 #endif
   8266     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
   8267     return OMX_ErrorNone;
   8268 }
   8269 
   8270 /* ======================================================================
   8271    FUNCTION
   8272    omx_vdec::UseEGLImage
   8273 
   8274    DESCRIPTION
   8275    OMX Use EGL Image method implementation <TBD>.
   8276 
   8277    PARAMETERS
   8278    <TBD>.
   8279 
   8280    RETURN VALUE
   8281    Not Implemented error.
   8282 
   8283    ========================================================================== */
   8284 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
   8285         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   8286         OMX_IN OMX_U32                        port,
   8287         OMX_IN OMX_PTR                     appData,
   8288         OMX_IN void*                      eglImage)
   8289 {
   8290     (void) appData;
   8291     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   8292     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   8293     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   8294 
   8295 #ifdef USE_EGL_IMAGE_GPU
   8296     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   8297     EGLint fd = -1, offset = 0,pmemPtr = 0;
   8298 #else
   8299     int fd = -1, offset = 0;
   8300 #endif
   8301     DEBUG_PRINT_HIGH("use EGL image support for decoder");
   8302     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   8303         DEBUG_PRINT_ERROR("Invalid EGL image");
   8304     }
   8305 #ifdef USE_EGL_IMAGE_GPU
   8306     if (m_display_id == NULL) {
   8307         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
   8308         return OMX_ErrorInsufficientResources;
   8309     }
   8310     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   8311         eglGetProcAddress("eglQueryImageKHR");
   8312     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
   8313     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
   8314     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
   8315 #else //with OMX test app
   8316     struct temp_egl {
   8317         int pmem_fd;
   8318         int offset;
   8319     };
   8320     struct temp_egl *temp_egl_id = NULL;
   8321     void * pmemPtr = (void *) eglImage;
   8322     temp_egl_id = (struct temp_egl *)eglImage;
   8323     if (temp_egl_id != NULL) {
   8324         fd = temp_egl_id->pmem_fd;
   8325         offset = temp_egl_id->offset;
   8326     }
   8327 #endif
   8328     if (fd < 0) {
   8329         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
   8330         return OMX_ErrorInsufficientResources;
   8331     }
   8332     pmem_info.pmem_fd = (OMX_U32) fd;
   8333     pmem_info.offset = (OMX_U32) offset;
   8334     pmem_entry.entry = (void *) &pmem_info;
   8335     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   8336     pmem_list.entryList = &pmem_entry;
   8337     pmem_list.nEntries = 1;
   8338     ouput_egl_buffers = true;
   8339     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   8340                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   8341                 (OMX_U8 *)pmemPtr)) {
   8342         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
   8343         return OMX_ErrorInsufficientResources;
   8344     }
   8345     return OMX_ErrorNone;
   8346 }
   8347 
   8348 /* ======================================================================
   8349    FUNCTION
   8350    omx_vdec::ComponentRoleEnum
   8351 
   8352    DESCRIPTION
   8353    OMX Component Role Enum method implementation.
   8354 
   8355    PARAMETERS
   8356    <TBD>.
   8357 
   8358    RETURN VALUE
   8359    OMX Error None if everything is successful.
   8360    ========================================================================== */
   8361 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   8362         OMX_OUT OMX_U8*        role,
   8363         OMX_IN OMX_U32        index)
   8364 {
   8365     (void) hComp;
   8366     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8367 
   8368     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   8369         if ((0 == index) && role) {
   8370             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   8371             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8372         } else {
   8373             eRet = OMX_ErrorNoMore;
   8374         }
   8375     }
   8376     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   8377         if ((0 == index) && role) {
   8378             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   8379             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8380         } else {
   8381             eRet = OMX_ErrorNoMore;
   8382         }
   8383     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   8384         if ((0 == index) && role) {
   8385             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   8386             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8387         } else {
   8388             DEBUG_PRINT_LOW("No more roles");
   8389             eRet = OMX_ErrorNoMore;
   8390         }
   8391     }
   8392 
   8393     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   8394             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) {
   8395         if ((0 == index) && role) {
   8396             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   8397             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8398         } else {
   8399             DEBUG_PRINT_LOW("No more roles");
   8400             eRet = OMX_ErrorNoMore;
   8401         }
   8402     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   8403         if ((0 == index) && role) {
   8404             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   8405             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8406         } else {
   8407             DEBUG_PRINT_LOW("No more roles");
   8408             eRet = OMX_ErrorNoMore;
   8409         }
   8410     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   8411         if ((0 == index) && role) {
   8412             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   8413             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8414         } else {
   8415             DEBUG_PRINT_LOW("No more roles");
   8416             eRet = OMX_ErrorNoMore;
   8417         }
   8418     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   8419         if ((0 == index) && role) {
   8420             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   8421             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   8422         } else {
   8423             DEBUG_PRINT_LOW("No more roles");
   8424             eRet = OMX_ErrorNoMore;
   8425         }
   8426     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   8427             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   8428           ) {
   8429         if ((0 == index) && role) {
   8430             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   8431             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8432         } else {
   8433             DEBUG_PRINT_LOW("No more roles");
   8434             eRet = OMX_ErrorNoMore;
   8435         }
   8436     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   8437         if ((0 == index) && role) {
   8438             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   8439             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8440         } else {
   8441             DEBUG_PRINT_LOW("No more roles");
   8442             eRet = OMX_ErrorNoMore;
   8443         }
   8444     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   8445         if ((0 == index) && role) {
   8446             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   8447             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   8448         } else {
   8449             DEBUG_PRINT_LOW("No more roles");
   8450             eRet = OMX_ErrorNoMore;
   8451         }
   8452     } else {
   8453         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
   8454         eRet = OMX_ErrorInvalidComponentName;
   8455     }
   8456     return eRet;
   8457 }
   8458 
   8459 
   8460 
   8461 
   8462 /* ======================================================================
   8463    FUNCTION
   8464    omx_vdec::AllocateDone
   8465 
   8466    DESCRIPTION
   8467    Checks if entire buffer pool is allocated by IL Client or not.
   8468    Need this to move to IDLE state.
   8469 
   8470    PARAMETERS
   8471    None.
   8472 
   8473    RETURN VALUE
   8474    true/false.
   8475 
   8476    ========================================================================== */
   8477 bool omx_vdec::allocate_done(void)
   8478 {
   8479     bool bRet = false;
   8480     bool bRet_In = false;
   8481     bool bRet_Out = false;
   8482     bool bRet_Out_Extra = false;
   8483 
   8484     bRet_In = allocate_input_done();
   8485     bRet_Out = allocate_output_done();
   8486     bRet_Out_Extra = allocate_output_extradata_done();
   8487 
   8488     if (bRet_In && bRet_Out && bRet_Out_Extra) {
   8489         bRet = true;
   8490     }
   8491 
   8492     return bRet;
   8493 }
   8494 /* ======================================================================
   8495    FUNCTION
   8496    omx_vdec::AllocateInputDone
   8497 
   8498    DESCRIPTION
   8499    Checks if I/P buffer pool is allocated by IL Client or not.
   8500 
   8501    PARAMETERS
   8502    None.
   8503 
   8504    RETURN VALUE
   8505    true/false.
   8506 
   8507    ========================================================================== */
   8508 bool omx_vdec::allocate_input_done(void)
   8509 {
   8510     bool bRet = false;
   8511     unsigned i=0;
   8512 
   8513     if (m_inp_mem_ptr == NULL) {
   8514         return bRet;
   8515     }
   8516     if (m_inp_mem_ptr ) {
   8517         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   8518             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   8519                 break;
   8520             }
   8521         }
   8522     }
   8523     if (i == drv_ctx.ip_buf.actualcount) {
   8524         bRet = true;
   8525         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   8526     }
   8527     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   8528         m_inp_bPopulated = OMX_TRUE;
   8529     }
   8530     return bRet;
   8531 }
   8532 /* ======================================================================
   8533    FUNCTION
   8534    omx_vdec::AllocateOutputDone
   8535 
   8536    DESCRIPTION
   8537    Checks if entire O/P buffer pool is allocated by IL Client or not.
   8538 
   8539    PARAMETERS
   8540    None.
   8541 
   8542    RETURN VALUE
   8543    true/false.
   8544 
   8545    ========================================================================== */
   8546 bool omx_vdec::allocate_output_done(void)
   8547 {
   8548     bool bRet = false;
   8549     unsigned j=0;
   8550 
   8551     if (m_out_mem_ptr == NULL) {
   8552         return bRet;
   8553     }
   8554 
   8555     if (m_out_mem_ptr) {
   8556         for (; j < drv_ctx.op_buf.actualcount; j++) {
   8557             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   8558                 break;
   8559             }
   8560         }
   8561     }
   8562 
   8563     if (j == drv_ctx.op_buf.actualcount) {
   8564         bRet = true;
   8565         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   8566         if (m_out_bEnabled)
   8567             m_out_bPopulated = OMX_TRUE;
   8568     }
   8569 
   8570     return bRet;
   8571 }
   8572 
   8573 bool omx_vdec::allocate_output_extradata_done(void) {
   8574     bool bRet = false;
   8575     unsigned j=0;
   8576     unsigned nBufferCount = 0;
   8577 
   8578     nBufferCount = m_client_out_extradata_info.getBufferCount();
   8579 
   8580     if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
   8581         return true;
   8582     }
   8583 
   8584     if (m_client_output_extradata_mem_ptr) {
   8585         for (; j < nBufferCount; j++) {
   8586             if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
   8587                 break;
   8588             }
   8589         }
   8590 
   8591         if (j == nBufferCount) {
   8592             bRet = true;
   8593             DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
   8594         }
   8595     }
   8596 
   8597     return bRet;
   8598 }
   8599 /* ======================================================================
   8600    FUNCTION
   8601    omx_vdec::ReleaseDone
   8602 
   8603    DESCRIPTION
   8604    Checks if IL client has released all the buffers.
   8605 
   8606    PARAMETERS
   8607    None.
   8608 
   8609    RETURN VALUE
   8610    true/false
   8611 
   8612    ========================================================================== */
   8613 bool omx_vdec::release_done(void)
   8614 {
   8615     bool bRet = false;
   8616 
   8617     if (release_input_done()) {
   8618         if (release_output_done()) {
   8619             if (release_output_extradata_done()) {
   8620                 bRet = true;
   8621             }
   8622         }
   8623     }
   8624     return bRet;
   8625 }
   8626 
   8627 
   8628 /* ======================================================================
   8629    FUNCTION
   8630    omx_vdec::ReleaseOutputDone
   8631 
   8632    DESCRIPTION
   8633    Checks if IL client has released all the buffers.
   8634 
   8635    PARAMETERS
   8636    None.
   8637 
   8638    RETURN VALUE
   8639    true/false
   8640 
   8641    ========================================================================== */
   8642 bool omx_vdec::release_output_done(void)
   8643 {
   8644     bool bRet = false;
   8645     unsigned i=0,j=0;
   8646 
   8647     DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr);
   8648     if (m_out_mem_ptr) {
   8649         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   8650             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   8651                 break;
   8652             }
   8653         }
   8654         if (j == drv_ctx.op_buf.actualcount) {
   8655             m_out_bm_count = 0;
   8656             bRet = true;
   8657         }
   8658     } else {
   8659         m_out_bm_count = 0;
   8660         bRet = true;
   8661     }
   8662     return bRet;
   8663 }
   8664 /* ======================================================================
   8665    FUNCTION
   8666    omx_vdec::ReleaseInputDone
   8667 
   8668    DESCRIPTION
   8669    Checks if IL client has released all the buffers.
   8670 
   8671    PARAMETERS
   8672    None.
   8673 
   8674    RETURN VALUE
   8675    true/false
   8676 
   8677    ========================================================================== */
   8678 bool omx_vdec::release_input_done(void)
   8679 {
   8680     bool bRet = false;
   8681     unsigned i=0,j=0;
   8682 
   8683     DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   8684     if (m_inp_mem_ptr) {
   8685         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   8686             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   8687                 break;
   8688             }
   8689         }
   8690         if (j==drv_ctx.ip_buf.actualcount) {
   8691             bRet = true;
   8692         }
   8693     } else {
   8694         bRet = true;
   8695     }
   8696     return bRet;
   8697 }
   8698 
   8699 bool omx_vdec::release_output_extradata_done(void) {
   8700     bool bRet = false;
   8701     unsigned i=0,j=0, buffer_count=0;
   8702 
   8703     buffer_count = m_client_out_extradata_info.getBufferCount();
   8704     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
   8705             m_client_output_extradata_mem_ptr, buffer_count);
   8706 
   8707     if (m_client_output_extradata_mem_ptr) {
   8708         for (; j<buffer_count; j++) {
   8709             if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
   8710                 break;
   8711             }
   8712         }
   8713         if (j == buffer_count) {
   8714             bRet = true;
   8715         }
   8716     } else {
   8717         bRet = true;
   8718     }
   8719     return bRet;
   8720 }
   8721 
   8722 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   8723         OMX_BUFFERHEADERTYPE * buffer)
   8724 {
   8725     VIDC_TRACE_NAME_HIGH("FBD");
   8726     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   8727     if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
   8728         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
   8729         return OMX_ErrorBadParameter;
   8730     } else if (output_flush_progress) {
   8731         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   8732         buffer->nFilledLen = 0;
   8733         buffer->nTimeStamp = 0;
   8734         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   8735         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8736         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   8737     }
   8738 
   8739     if (m_debug_extradata) {
   8740         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   8741             DEBUG_PRINT_HIGH("***************************************************");
   8742             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   8743             DEBUG_PRINT_HIGH("***************************************************");
   8744         }
   8745 
   8746         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   8747             DEBUG_PRINT_HIGH("***************************************************");
   8748             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   8749             DEBUG_PRINT_HIGH("***************************************************");
   8750         }
   8751     }
   8752 
   8753 
   8754     DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld",
   8755             buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp);
   8756     pending_output_buffers --;
   8757     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
   8758 
   8759     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8760         DEBUG_PRINT_HIGH("Output EOS has been reached");
   8761         if (!output_flush_progress)
   8762             post_event((unsigned)NULL, (unsigned)NULL,
   8763                     OMX_COMPONENT_GENERATE_EOS_DONE);
   8764 
   8765         if (psource_frame) {
   8766             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   8767             psource_frame = NULL;
   8768         }
   8769         if (pdest_frame) {
   8770             pdest_frame->nFilledLen = 0;
   8771             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
   8772                     (unsigned)NULL);
   8773             pdest_frame = NULL;
   8774         }
   8775     }
   8776 
   8777 #ifdef OUTPUT_EXTRADATA_LOG
   8778     if (outputExtradataFile) {
   8779         int buf_index = buffer - m_out_mem_ptr;
   8780         OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
   8781 
   8782         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   8783         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   8784             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
   8785 
   8786         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
   8787             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
   8788                                     p_extra->nSize, p_extra->eType);
   8789             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   8790 
   8791             if (p_extra->eType == OMX_ExtraDataNone) {
   8792                 break;
   8793             }
   8794             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   8795         }
   8796     }
   8797 #endif
   8798 
   8799     /* For use buffer we need to copy the data */
   8800     if (!output_flush_progress) {
   8801         /* This is the error check for non-recoverable errros */
   8802         bool is_duplicate_ts_valid = true;
   8803         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   8804 
   8805         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   8806                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   8807                 output_capability == V4L2_PIX_FMT_DIVX ||
   8808                 output_capability == V4L2_PIX_FMT_DIVX_311)
   8809             is_duplicate_ts_valid = false;
   8810 
   8811         if ((output_capability == V4L2_PIX_FMT_H264 ||
   8812                 output_capability == V4L2_PIX_FMT_H264_MVC) &&
   8813                 is_interlaced) {
   8814             if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
   8815                 is_interlaced = false;
   8816             }
   8817         }
   8818 
   8819         if (buffer->nFilledLen > 0) {
   8820             time_stamp_dts.get_next_timestamp(buffer,
   8821                     is_interlaced && is_duplicate_ts_valid);
   8822             if (m_debug_timestamp) {
   8823                 {
   8824                     OMX_TICKS expected_ts = 0;
   8825                     m_timestamp_list.pop_min_ts(expected_ts);
   8826                     if (is_interlaced && is_duplicate_ts_valid) {
   8827                         m_timestamp_list.pop_min_ts(expected_ts);
   8828                     }
   8829                     DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   8830                             buffer->nTimeStamp, expected_ts);
   8831 
   8832                     if (buffer->nTimeStamp != expected_ts) {
   8833                         DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
   8834                     }
   8835                 }
   8836             }
   8837         }
   8838     }
   8839     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
   8840 
   8841     if (m_cb.FillBufferDone) {
   8842         if (buffer->nFilledLen > 0) {
   8843             if (arbitrary_bytes)
   8844                 adjust_timestamp(buffer->nTimeStamp);
   8845             else
   8846                 set_frame_rate(buffer->nTimeStamp);
   8847 
   8848             proc_frms++;
   8849             if (perf_flag) {
   8850                 if (1 == proc_frms) {
   8851                     dec_time.stop();
   8852                     latency = dec_time.processing_time_us() - latency;
   8853                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   8854                     dec_time.start();
   8855                     fps_metrics.start();
   8856                 }
   8857                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8858                     OMX_U64 proc_time = 0;
   8859                     fps_metrics.stop();
   8860                     proc_time = fps_metrics.processing_time_us();
   8861                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
   8862                             (unsigned int)proc_frms, (float)proc_time / 1e6,
   8863                             (float)(1e6 * proc_frms) / proc_time);
   8864                 }
   8865             }
   8866         }
   8867         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8868             prev_ts = LLONG_MAX;
   8869             rst_prev_ts = true;
   8870             proc_frms = 0;
   8871         }
   8872 
   8873         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   8874             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   8875              buffer->pPlatformPrivate)->entryList->entry;
   8876         DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   8877         OMX_BUFFERHEADERTYPE *il_buffer;
   8878         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   8879         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
   8880 
   8881         if (il_buffer && m_last_rendered_TS >= 0) {
   8882             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
   8883 
   8884             // Current frame can be send for rendering if
   8885             // (a) current FPS is <=  60
   8886             // (b) is the next frame after the frame with TS 0
   8887             // (c) is the first frame after seek
   8888             // (d) the delta TS b\w two consecutive frames is > 16 ms
   8889             // (e) its TS is equal to previous frame TS
   8890             // (f) if marked EOS
   8891 
   8892             if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
   8893                il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
   8894                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   8895                m_last_rendered_TS = il_buffer->nTimeStamp;
   8896             } else {
   8897                //mark for droping
   8898                buffer->nFilledLen = 0;
   8899             }
   8900 
   8901             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
   8902                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
   8903                               il_buffer->nTimeStamp,ts_delta);
   8904 
   8905             //above code makes sure that delta b\w two consecutive frames is not
   8906             //greater than 16ms, slow-mo feature, so cap fps to max 60
   8907             if (current_framerate > 60 ) {
   8908                 current_framerate = 60;
   8909             }
   8910         }
   8911 
   8912         // add current framerate to gralloc meta data
   8913         if ((buffer->nFilledLen > 0) && m_enable_android_native_buffers && m_out_mem_ptr) {
   8914             // If valid fps was received, directly send it to display for the 1st fbd.
   8915             // Otherwise, calculate fps using fbd timestamps
   8916             float refresh_rate = m_fps_prev;
   8917             if (m_fps_received) {
   8918                 if (1 == proc_frms) {
   8919                     refresh_rate = m_fps_received / (float)(1<<16);
   8920                 }
   8921             } else {
   8922                 // check if dynamic refresh rate change feature enabled or not
   8923                 if (m_drc_enable) {
   8924                     // set coarse fps when 2 fbds received and
   8925                     // set fps again when 30 fbds received as it should be
   8926                     // more accurate than the one set when only 2 fbds received.
   8927                     if (2 == proc_frms || 30 == proc_frms) {
   8928                         if (drv_ctx.frame_rate.fps_denominator) {
   8929                             refresh_rate = drv_ctx.frame_rate.fps_numerator /
   8930                                     (float) drv_ctx.frame_rate.fps_denominator;
   8931                         }
   8932                     }
   8933                 } else {
   8934                     // calculate and set refresh rate for every frame from second frame onwards
   8935                     // display will assume the default refresh rate for first frame (which is 60 fps)
   8936                     if (m_fps_prev) {
   8937                         if (drv_ctx.frame_rate.fps_denominator) {
   8938                             refresh_rate = drv_ctx.frame_rate.fps_numerator /
   8939                                     (float) drv_ctx.frame_rate.fps_denominator;
   8940                         }
   8941                     }
   8942                 }
   8943             }
   8944             if (refresh_rate > 60) {
   8945                 refresh_rate = 60;
   8946             }
   8947             DEBUG_PRINT_LOW("frc set refresh_rate %f, frame %d", refresh_rate, proc_frms);
   8948             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8949             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8950                          UPDATE_REFRESH_RATE, (void*)&refresh_rate);
   8951             m_fps_prev = refresh_rate;
   8952         }
   8953 
   8954         if (buffer->nFilledLen && m_enable_android_native_buffers && m_out_mem_ptr) {
   8955             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8956             DEBUG_PRINT_LOW("stereo_output_mode = %d",stereo_output_mode);
   8957             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8958                                S3D_FORMAT, (void*)&stereo_output_mode);
   8959         }
   8960 
   8961         if (il_buffer) {
   8962             log_output_buffers(il_buffer);
   8963             if (dynamic_buf_mode) {
   8964                 unsigned int nPortIndex = 0;
   8965                 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8966 
   8967                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
   8968                 // to size of the handle. Do it _after_ log_output_buffers which
   8969                 // requires the respective sizes to be accurate.
   8970 
   8971                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   8972                 buffer->nFilledLen = buffer->nFilledLen ?
   8973                         sizeof(struct VideoDecoderOutputMetaData) : 0;
   8974 
   8975                 //Clear graphic buffer handles in dynamic mode
   8976                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
   8977                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   8978                     native_buffer[nPortIndex].privatehandle = NULL;
   8979                     native_buffer[nPortIndex].nativehandle = NULL;
   8980                 } else {
   8981                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
   8982                     return OMX_ErrorBadParameter;
   8983                 }
   8984             }
   8985             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   8986         } else {
   8987             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   8988             return OMX_ErrorBadParameter;
   8989         }
   8990         DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   8991     } else {
   8992         return OMX_ErrorBadParameter;
   8993     }
   8994 
   8995 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   8996     if (m_smoothstreaming_mode && m_out_mem_ptr) {
   8997         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8998         BufferDim_t dim;
   8999         private_handle_t *private_handle = NULL;
   9000         dim.sliceWidth = framesize.nWidth;
   9001         dim.sliceHeight = framesize.nHeight;
   9002         if (buf_index < drv_ctx.op_buf.actualcount &&
   9003             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   9004             native_buffer[buf_index].privatehandle)
   9005             private_handle = native_buffer[buf_index].privatehandle;
   9006         if (private_handle) {
   9007             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   9008                 dim.sliceWidth, dim.sliceHeight);
   9009             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   9010         }
   9011     }
   9012 #endif
   9013 
   9014     return OMX_ErrorNone;
   9015 }
   9016 
   9017 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   9018         OMX_BUFFERHEADERTYPE* buffer)
   9019 {
   9020     VIDC_TRACE_NAME_HIGH("EBD");
   9021     int nBufferIndex = buffer - m_inp_mem_ptr;
   9022 
   9023     if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
   9024         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
   9025         return OMX_ErrorBadParameter;
   9026     }
   9027 
   9028     DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x",
   9029             buffer, buffer->pBuffer, buffer->nFlags);
   9030     pending_input_buffers--;
   9031     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   9032 
   9033     if (arbitrary_bytes) {
   9034         if (pdest_frame == NULL && input_flush_progress == false) {
   9035             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
   9036             pdest_frame = buffer;
   9037             buffer->nFilledLen = 0;
   9038             buffer->nTimeStamp = LLONG_MAX;
   9039             push_input_buffer (hComp);
   9040         } else {
   9041             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
   9042             buffer->nFilledLen = 0;
   9043             if (!m_input_free_q.insert_entry((unsigned long)buffer,
   9044                         (unsigned)NULL, (unsigned)NULL)) {
   9045                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
   9046             }
   9047         }
   9048     } else if (m_cb.EmptyBufferDone) {
   9049         buffer->nFilledLen = 0;
   9050         if (input_use_buffer == true) {
   9051             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   9052         }
   9053 
   9054         /* Restore the FD that we over-wrote in ETB */
   9055         if (m_input_pass_buffer_fd) {
   9056             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
   9057         }
   9058 
   9059         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   9060     }
   9061     return OMX_ErrorNone;
   9062 }
   9063 
   9064 int omx_vdec::async_message_process (void *context, void* message)
   9065 {
   9066     omx_vdec* omx = NULL;
   9067     struct vdec_msginfo *vdec_msg = NULL;
   9068     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   9069     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   9070     struct v4l2_plane *plane = NULL;
   9071     struct vdec_output_frameinfo *output_respbuf = NULL;
   9072     int rc=1;
   9073     if (context == NULL || message == NULL) {
   9074         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
   9075         return -1;
   9076     }
   9077     vdec_msg = (struct vdec_msginfo *)message;
   9078 
   9079     omx = reinterpret_cast<omx_vdec*>(context);
   9080 
   9081     switch (vdec_msg->msgcode) {
   9082 
   9083         case VDEC_MSG_EVT_HW_ERROR:
   9084             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9085                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9086             break;
   9087 
   9088         case VDEC_MSG_EVT_HW_OVERLOAD:
   9089             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9090                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
   9091             break;
   9092 
   9093         case VDEC_MSG_EVT_HW_UNSUPPORTED:
   9094             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9095                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   9096             break;
   9097 
   9098         case VDEC_MSG_RESP_START_DONE:
   9099             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9100                     OMX_COMPONENT_GENERATE_START_DONE);
   9101             break;
   9102 
   9103         case VDEC_MSG_RESP_STOP_DONE:
   9104             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9105                     OMX_COMPONENT_GENERATE_STOP_DONE);
   9106             break;
   9107 
   9108         case VDEC_MSG_RESP_RESUME_DONE:
   9109             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9110                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   9111             break;
   9112 
   9113         case VDEC_MSG_RESP_PAUSE_DONE:
   9114             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9115                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   9116             break;
   9117 
   9118         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   9119             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9120                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   9121             break;
   9122         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   9123             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9124                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   9125             break;
   9126         case VDEC_MSG_RESP_INPUT_FLUSHED:
   9127         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   9128 
   9129             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   9130                vdec_msg->msgdata.input_frame_clientdata; */
   9131 
   9132             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   9133             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
   9134                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
   9135                 omxhdr = NULL;
   9136                 vdec_msg->status_code = VDEC_S_EFATAL;
   9137                 break;
   9138 
   9139             }
   9140             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
   9141 
   9142             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   9143                 DEBUG_PRINT_HIGH("Unsupported input");
   9144                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   9145                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9146             }
   9147             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   9148                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   9149                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   9150             }
   9151             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   9152 
   9153                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
   9154                 android_atomic_dec(&omx->m_queued_codec_config_count);
   9155                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
   9156                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
   9157                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
   9158                     sem_post(&omx->m_safe_flush);
   9159                 }
   9160             }
   9161             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME ||
   9162                 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   9163                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   9164             }
   9165             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
   9166                     OMX_COMPONENT_GENERATE_EBD);
   9167             break;
   9168         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   9169             int64_t *timestamp;
   9170             timestamp = (int64_t *) malloc(sizeof(int64_t));
   9171             if (timestamp) {
   9172                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   9173                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
   9174                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   9175                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
   9176                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
   9177             }
   9178             break;
   9179         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   9180         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   9181 
   9182            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   9183            if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL ||
   9184                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
   9185                omxhdr = NULL;
   9186                vdec_msg->status_code = VDEC_S_EFATAL;
   9187                break;
   9188            }
   9189            plane = v4l2_buf_ptr->m.planes;
   9190            omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index;
   9191 
   9192            if (omxhdr && omxhdr->pOutputPortPrivate &&
   9193                    ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
   9194                    (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   9195                      - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
   9196 
   9197                if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   9198                    omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   9199                    omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   9200                    omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   9201                    omxhdr->nFlags = 0;
   9202 
   9203                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
   9204                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   9205                         //rc = -1;
   9206                    }
   9207                    if (omxhdr->nFilledLen) {
   9208                        omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   9209                    }
   9210                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   9211                        omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   9212                    } else {
   9213                        omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   9214                    }
   9215                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   9216                        omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   9217                    }
   9218                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   9219                        omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   9220                    }
   9221                    if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
   9222                        omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
   9223                    }
   9224                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   9225                         omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
   9226                         DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   9227                                    omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   9228                    }
   9229 
   9230                    if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   9231                            !omx->output_flush_progress &&
   9232                            !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   9233                            !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
   9234                        omx->time_stamp_dts.remove_time_stamp(
   9235                                omxhdr->nTimeStamp,
   9236                                (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   9237                                ?true:false);
   9238 
   9239                        omxhdr->nFilledLen = 0;
   9240                        omx->pending_output_buffers--;
   9241                        omx->post_event ((unsigned long)NULL,(unsigned long)omx->client_buffers.get_il_buf_hdr(omxhdr),
   9242                                OMX_COMPONENT_GENERATE_FTB);
   9243                        break;
   9244                    }
   9245                    if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   9246                        omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   9247                    }
   9248 
   9249                    output_respbuf = (struct vdec_output_frameinfo *)\
   9250                             omxhdr->pOutputPortPrivate;
   9251                    if (!output_respbuf) {
   9252                      DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
   9253                      return -1;
   9254                    }
   9255                    output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   9256                    output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   9257 
   9258                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   9259                        output_respbuf->pic_type = PICTURE_TYPE_I;
   9260                    }
   9261                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   9262                        output_respbuf->pic_type = PICTURE_TYPE_P;
   9263                    }
   9264                    if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   9265                        output_respbuf->pic_type = PICTURE_TYPE_B;
   9266                    }
   9267 
   9268                    if (vdec_msg->msgdata.output_frame.len) {
   9269                        if (!omx->output_flush_progress && (omxhdr->nFilledLen > 0)) {
   9270                            // set the default colorspace advised by client, since the bitstream may be
   9271                            // devoid of colorspace-info.
   9272                            if (omx->m_enable_android_native_buffers) {
   9273                                ColorSpace_t color_space = ITU_R_601;
   9274 
   9275                            // Disabled ?
   9276                            // WA for VP8. Vp8 encoder does not embed color-info (yet!).
   9277                            // Encoding RGBA results in 601-LR for all resolutions.
   9278                            // This conflicts with the client't defaults which are based on resolution.
   9279                            //   Eg: 720p will be encoded as 601-LR. Client will say 709.
   9280                            // Re-enable this code once vp8 encoder generates color-info and hence the
   9281                            // decoder will be able to override with the correct source color.
   9282 #if 0
   9283                                switch (omx->m_client_color_space.sAspects.mPrimaries) {
   9284                                    case ColorAspects::PrimariesBT601_6_625:
   9285                                    case ColorAspects::PrimariesBT601_6_525:
   9286                                    {
   9287                                        color_space = omx->m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
   9288                                                ITU_R_601_FR : ITU_R_601;
   9289                                        break;
   9290                                    }
   9291                                    case ColorAspects::PrimariesBT709_5:
   9292                                    {
   9293                                        color_space = ITU_R_709;
   9294                                        break;
   9295                                    }
   9296                                    default:
   9297                                    {
   9298                                        break;
   9299                                    }
   9300                                }
   9301 #endif
   9302                                DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
   9303                                        color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   9304                                omx->set_colorspace_in_handle(color_space, omxhdr - omx->m_out_mem_ptr);
   9305                            }
   9306                        }
   9307 
   9308                        DEBUG_PRINT_LOW("Processing extradata");
   9309                        omx->handle_extradata(omxhdr);
   9310 
   9311                        if (omx->m_extradata_info.output_crop_updated) {
   9312                            DEBUG_PRINT_LOW("Read FBD crop from output extra data");
   9313                            vdec_msg->msgdata.output_frame.framesize.left = omx->m_extradata_info.output_crop_rect.nLeft;
   9314                            vdec_msg->msgdata.output_frame.framesize.top = omx->m_extradata_info.output_crop_rect.nTop;
   9315                            vdec_msg->msgdata.output_frame.framesize.right = omx->m_extradata_info.output_crop_rect.nWidth;
   9316                            vdec_msg->msgdata.output_frame.framesize.bottom = omx->m_extradata_info.output_crop_rect.nHeight;
   9317                            vdec_msg->msgdata.output_frame.picsize.frame_width = omx->m_extradata_info.output_width;
   9318                            vdec_msg->msgdata.output_frame.picsize.frame_height = omx->m_extradata_info.output_height;
   9319                        } else {
   9320                            DEBUG_PRINT_LOW("Read FBD crop from v4l2 reserved fields");
   9321                            vdec_msg->msgdata.output_frame.framesize.left = plane[0].reserved[2];
   9322                            vdec_msg->msgdata.output_frame.framesize.top = plane[0].reserved[3];
   9323                            vdec_msg->msgdata.output_frame.framesize.right = plane[0].reserved[2] + plane[0].reserved[4];
   9324                            vdec_msg->msgdata.output_frame.framesize.bottom = plane[0].reserved[3] + plane[0].reserved[5];
   9325                            vdec_msg->msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
   9326                            vdec_msg->msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
   9327 
   9328                            /* Copy these values back to OMX internal variables to make both handlign same*/
   9329 
   9330                            omx->m_extradata_info.output_crop_rect.nLeft = vdec_msg->msgdata.output_frame.framesize.left;
   9331                            omx->m_extradata_info.output_crop_rect.nTop = vdec_msg->msgdata.output_frame.framesize.top;
   9332                            omx->m_extradata_info.output_crop_rect.nWidth = vdec_msg->msgdata.output_frame.framesize.right;
   9333                            omx->m_extradata_info.output_crop_rect.nHeight = vdec_msg->msgdata.output_frame.framesize.bottom;
   9334                            omx->m_extradata_info.output_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   9335                            omx->m_extradata_info.output_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   9336                        }
   9337                    }
   9338 
   9339                    vdec_msg->msgdata.output_frame.bufferaddr =
   9340                        omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   9341 
   9342                    if (vdec_msg->msgdata.output_frame.len)
   9343                        memcpy(&omx->drv_ctx.frame_size,
   9344                                &vdec_msg->msgdata.output_frame.framesize,
   9345                                sizeof(struct vdec_framesize));
   9346 
   9347                    DEBUG_PRINT_LOW("[RespBufDone] Fd(%d) Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x)"
   9348                            " FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
   9349                            omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
   9350                            omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
   9351                            vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
   9352                            (unsigned int)vdec_msg->msgdata.output_frame.len,
   9353                            vdec_msg->msgdata.output_frame.framesize.left,
   9354                            vdec_msg->msgdata.output_frame.framesize.top,
   9355                            vdec_msg->msgdata.output_frame.framesize.right,
   9356                            vdec_msg->msgdata.output_frame.framesize.bottom);
   9357 
   9358                    /* Post event if resolution OR crop changed */
   9359                    /* filled length will be changed if resolution changed */
   9360                    /* Crop parameters can be changed even without resolution change */
   9361                    if (omxhdr->nFilledLen
   9362                        && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
   9363                        || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
   9364                        || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
   9365                        || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
   9366                        || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
   9367                        || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
   9368                        || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
   9369 
   9370                        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",
   9371                                omx->prev_n_filled_len,
   9372                                omx->drv_ctx.video_resolution.frame_width,
   9373                                omx->drv_ctx.video_resolution.frame_height,
   9374                                omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
   9375                                omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
   9376                                omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
   9377                                vdec_msg->msgdata.output_frame.picsize.frame_height,
   9378                                vdec_msg->msgdata.output_frame.framesize.left,
   9379                                vdec_msg->msgdata.output_frame.framesize.top,
   9380                                vdec_msg->msgdata.output_frame.framesize.right,
   9381                                vdec_msg->msgdata.output_frame.framesize.bottom);
   9382 
   9383                        omx->drv_ctx.video_resolution.frame_width =
   9384                                vdec_msg->msgdata.output_frame.picsize.frame_width;
   9385                        omx->drv_ctx.video_resolution.frame_height =
   9386                                vdec_msg->msgdata.output_frame.picsize.frame_height;
   9387                        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   9388                            omx->drv_ctx.video_resolution.stride =
   9389                                VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
   9390                            omx->drv_ctx.video_resolution.scan_lines =
   9391                                VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
   9392                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   9393                            omx->drv_ctx.video_resolution.stride =
   9394                                VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
   9395                            omx->drv_ctx.video_resolution.scan_lines =
   9396                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
   9397                        } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   9398                            omx->drv_ctx.video_resolution.stride =
   9399                                VENUS_Y_STRIDE(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_width);
   9400                            omx->drv_ctx.video_resolution.scan_lines =
   9401                                VENUS_Y_SCANLINES(COLOR_FMT_NV12_BPP10_UBWC, omx->drv_ctx.video_resolution.frame_height);
   9402                         }
   9403 
   9404                        omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   9405                                 OMX_IndexConfigCommonOutputCrop,
   9406                                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   9407                    }
   9408 
   9409                    if (omxhdr->nFilledLen)
   9410                        omx->prev_n_filled_len = omxhdr->nFilledLen;
   9411 
   9412                    if (omxhdr && omxhdr->nFilledLen && !omx->m_need_turbo) {
   9413                         omx->request_perf_level(VIDC_NOMINAL);
   9414                    }
   9415                    if (omx->output_use_buffer && omxhdr->pBuffer &&
   9416                        vdec_msg->msgdata.output_frame.bufferaddr)
   9417                        memcpy ( omxhdr->pBuffer, (void *)
   9418                                ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   9419                                 (unsigned long)vdec_msg->msgdata.output_frame.offset),
   9420                                vdec_msg->msgdata.output_frame.len);
   9421                } else {
   9422                    DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
   9423                            (unsigned int)vdec_msg->msgdata.output_frame.len,
   9424                            omxhdr->nAllocLen, omx->prev_n_filled_len);
   9425                    omxhdr->nFilledLen = 0;
   9426                }
   9427 
   9428                omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
   9429                         OMX_COMPONENT_GENERATE_FBD);
   9430 
   9431             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
   9432                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
   9433                         OMX_COMPONENT_GENERATE_EOS_DONE);
   9434             } else {
   9435                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   9436                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   9437             }
   9438             break;
   9439         case VDEC_MSG_EVT_CONFIG_CHANGED:
   9440             DEBUG_PRINT_HIGH("Port settings changed");
   9441             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   9442             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   9443             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   9444                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   9445             if (!omx->m_need_turbo) {
   9446                 omx->request_perf_level(VIDC_NOMINAL);
   9447             }
   9448             break;
   9449         default:
   9450             break;
   9451     }
   9452     return rc;
   9453 }
   9454 
   9455 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   9456         OMX_HANDLETYPE hComp,
   9457         OMX_BUFFERHEADERTYPE *buffer
   9458         )
   9459 {
   9460     unsigned address,p2,id;
   9461     DEBUG_PRINT_LOW("Empty this arbitrary");
   9462 
   9463     if (buffer == NULL) {
   9464         return OMX_ErrorBadParameter;
   9465     }
   9466     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   9467     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
   9468             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
   9469 
   9470     /* return zero length and not an EOS buffer */
   9471     /* return buffer if input flush in progress */
   9472     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   9473                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   9474         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
   9475         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   9476         return OMX_ErrorNone;
   9477     }
   9478 
   9479     if (psource_frame == NULL) {
   9480         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   9481         psource_frame = buffer;
   9482         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
   9483         push_input_buffer (hComp);
   9484     } else {
   9485         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
   9486         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
   9487                     (unsigned)NULL)) {
   9488             return OMX_ErrorBadParameter;
   9489         }
   9490     }
   9491 
   9492     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   9493         codec_config_flag = false;
   9494     }
   9495     return OMX_ErrorNone;
   9496 }
   9497 
   9498 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   9499 {
   9500     unsigned long address,p2,id;
   9501     OMX_ERRORTYPE ret = OMX_ErrorNone;
   9502 
   9503     if (pdest_frame == NULL || psource_frame == NULL) {
   9504         /*Check if we have a destination buffer*/
   9505         if (pdest_frame == NULL) {
   9506             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
   9507             if (m_input_free_q.m_size) {
   9508                 m_input_free_q.pop_entry(&address,&p2,&id);
   9509                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   9510                 pdest_frame->nFilledLen = 0;
   9511                 pdest_frame->nTimeStamp = LLONG_MAX;
   9512                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
   9513             }
   9514         }
   9515 
   9516         /*Check if we have a destination buffer*/
   9517         if (psource_frame == NULL) {
   9518             DEBUG_PRINT_LOW("Get a source buffer from the queue");
   9519             if (m_input_pending_q.m_size) {
   9520                 m_input_pending_q.pop_entry(&address,&p2,&id);
   9521                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   9522                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   9523                         psource_frame->nTimeStamp);
   9524                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   9525                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9526 
   9527             }
   9528         }
   9529 
   9530     }
   9531 
   9532     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   9533         switch (codec_type_parse) {
   9534             case CODEC_TYPE_MPEG4:
   9535             case CODEC_TYPE_H263:
   9536             case CODEC_TYPE_MPEG2:
   9537                 ret =  push_input_sc_codec(hComp);
   9538                 break;
   9539             case CODEC_TYPE_H264:
   9540                 ret = push_input_h264(hComp);
   9541                 break;
   9542             case CODEC_TYPE_HEVC:
   9543                 ret = push_input_hevc(hComp);
   9544                 break;
   9545             case CODEC_TYPE_VC1:
   9546                 ret = push_input_vc1(hComp);
   9547                 break;
   9548             default:
   9549                 break;
   9550         }
   9551         if (ret != OMX_ErrorNone) {
   9552             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
   9553             omx_report_error ();
   9554             break;
   9555         }
   9556     }
   9557 
   9558     return ret;
   9559 }
   9560 
   9561 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   9562 {
   9563     OMX_U32 partial_frame = 1;
   9564     OMX_BOOL generate_ebd = OMX_TRUE;
   9565     unsigned long address = 0, p2 = 0, id = 0;
   9566 
   9567     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
   9568             psource_frame,psource_frame->nTimeStamp);
   9569     if (m_frame_parser.parse_sc_frame(psource_frame,
   9570                 pdest_frame,&partial_frame) == -1) {
   9571         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9572         return OMX_ErrorBadParameter;
   9573     }
   9574 
   9575     if (partial_frame == 0) {
   9576         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
   9577                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
   9578 
   9579 
   9580         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
   9581         /*First Parsed buffer will have only header Hence skip*/
   9582         if (frame_count == 0) {
   9583             DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
   9584 
   9585             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   9586                     codec_type_parse == CODEC_TYPE_DIVX) {
   9587                 mp4StreamType psBits;
   9588                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   9589                 psBits.numBytes = pdest_frame->nFilledLen;
   9590                 mp4_headerparser.parseHeader(&psBits);
   9591             }
   9592 
   9593             frame_count++;
   9594         } else {
   9595             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9596             if (pdest_frame->nFilledLen) {
   9597                 /*Push the frame to the Decoder*/
   9598                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9599                     return OMX_ErrorBadParameter;
   9600                 }
   9601                 frame_count++;
   9602                 pdest_frame = NULL;
   9603 
   9604                 if (m_input_free_q.m_size) {
   9605                     m_input_free_q.pop_entry(&address,&p2,&id);
   9606                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9607                     pdest_frame->nFilledLen = 0;
   9608                 }
   9609             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   9610                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
   9611                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
   9612                         (unsigned)NULL);
   9613                 pdest_frame = NULL;
   9614             }
   9615         }
   9616     } else {
   9617         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
   9618         /*Check if Destination Buffer is full*/
   9619         if (pdest_frame->nAllocLen ==
   9620                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   9621             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
   9622             return OMX_ErrorStreamCorrupt;
   9623         }
   9624     }
   9625 
   9626     if (psource_frame->nFilledLen == 0) {
   9627         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9628             if (pdest_frame) {
   9629                 pdest_frame->nFlags |= psource_frame->nFlags;
   9630                 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
   9631                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
   9632                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9633                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   9634                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   9635                 /*Push the frame to the Decoder*/
   9636                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9637                     return OMX_ErrorBadParameter;
   9638                 }
   9639                 frame_count++;
   9640                 pdest_frame = NULL;
   9641             } else {
   9642                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
   9643                 generate_ebd = OMX_FALSE;
   9644             }
   9645         }
   9646         if (generate_ebd) {
   9647             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
   9648             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9649             psource_frame = NULL;
   9650 
   9651             if (m_input_pending_q.m_size) {
   9652                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9653                 m_input_pending_q.pop_entry(&address,&p2,&id);
   9654                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9655                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   9656                         psource_frame->nTimeStamp);
   9657                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   9658                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9659             }
   9660         }
   9661     }
   9662     return OMX_ErrorNone;
   9663 }
   9664 
   9665 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   9666 {
   9667     OMX_U32 partial_frame = 1;
   9668     unsigned long address = 0, p2 = 0, id = 0;
   9669     OMX_BOOL isNewFrame = OMX_FALSE;
   9670     OMX_BOOL generate_ebd = OMX_TRUE;
   9671 
   9672     if (h264_scratch.pBuffer == NULL) {
   9673         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
   9674         return OMX_ErrorBadParameter;
   9675     }
   9676     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
   9677             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
   9678     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
   9679     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9680         look_ahead_nal = false;
   9681         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9682                 h264_scratch.nFilledLen) {
   9683             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9684                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9685             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9686             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
   9687             h264_scratch.nFilledLen = 0;
   9688         } else {
   9689             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
   9690             return OMX_ErrorBadParameter;
   9691         }
   9692     }
   9693 
   9694     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   9695        in EOS flag getting associated with the destination
   9696     */
   9697     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   9698             pdest_frame->nFilledLen) {
   9699         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   9700         generate_ebd = OMX_FALSE;
   9701     }
   9702 
   9703     if (nal_length == 0) {
   9704         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
   9705         if (m_frame_parser.parse_sc_frame(psource_frame,
   9706                     &h264_scratch,&partial_frame) == -1) {
   9707             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9708             return OMX_ErrorBadParameter;
   9709         }
   9710     } else {
   9711         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   9712         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9713                     &h264_scratch,&partial_frame) == -1) {
   9714             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9715             return OMX_ErrorBadParameter;
   9716         }
   9717     }
   9718 
   9719     if (partial_frame == 0) {
   9720         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9721             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9722             nal_count++;
   9723             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9724             h264_scratch.nFlags = psource_frame->nFlags;
   9725         } else {
   9726             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
   9727             if (h264_scratch.nFilledLen) {
   9728                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   9729                         NALU_TYPE_SPS);
   9730 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9731                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   9732                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9733                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9734                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9735                     // If timeinfo is present frame info from SEI is already processed
   9736                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9737                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9738 #endif
   9739                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9740                 nal_count++;
   9741                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   9742                     pdest_frame->nTimeStamp = h264_last_au_ts;
   9743                     pdest_frame->nFlags = h264_last_au_flags;
   9744 #ifdef PANSCAN_HDLR
   9745                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9746                         h264_parser->update_panscan_data(h264_last_au_ts);
   9747 #endif
   9748                 }
   9749                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   9750                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   9751                     h264_last_au_ts = h264_scratch.nTimeStamp;
   9752                     h264_last_au_flags = h264_scratch.nFlags;
   9753 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9754                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9755                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   9756                         if (!VALID_TS(h264_last_au_ts))
   9757                             h264_last_au_ts = ts_in_sei;
   9758                     }
   9759 #endif
   9760                 } else
   9761                     h264_last_au_ts = LLONG_MAX;
   9762             }
   9763 
   9764             if (!isNewFrame) {
   9765                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9766                         h264_scratch.nFilledLen) {
   9767                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
   9768                             (unsigned int)h264_scratch.nFilledLen);
   9769                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9770                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9771                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9772                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   9773                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   9774                     h264_scratch.nFilledLen = 0;
   9775                 } else {
   9776                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
   9777                     return OMX_ErrorBadParameter;
   9778                 }
   9779             } else if(h264_scratch.nFilledLen) {
   9780                 look_ahead_nal = true;
   9781                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
   9782                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9783                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   9784                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   9785 
   9786                 if (pdest_frame->nFilledLen == 0) {
   9787                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
   9788                     look_ahead_nal = false;
   9789                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9790                             h264_scratch.nFilledLen) {
   9791                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9792                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9793                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9794                         h264_scratch.nFilledLen = 0;
   9795                     } else {
   9796                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
   9797                         return OMX_ErrorBadParameter;
   9798                     }
   9799                 } else {
   9800                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   9801                         DEBUG_PRINT_LOW("Reset the EOS Flag");
   9802                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9803                     }
   9804                     /*Push the frame to the Decoder*/
   9805                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9806                         return OMX_ErrorBadParameter;
   9807                     }
   9808                     //frame_count++;
   9809                     pdest_frame = NULL;
   9810                     if (m_input_free_q.m_size) {
   9811                         m_input_free_q.pop_entry(&address,&p2,&id);
   9812                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9813                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
   9814                         pdest_frame->nFilledLen = 0;
   9815                         pdest_frame->nFlags = 0;
   9816                         pdest_frame->nTimeStamp = LLONG_MAX;
   9817                     }
   9818                 }
   9819             }
   9820         }
   9821     } else {
   9822         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
   9823         /*Check if Destination Buffer is full*/
   9824         if (h264_scratch.nAllocLen ==
   9825                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   9826             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   9827             return OMX_ErrorStreamCorrupt;
   9828         }
   9829     }
   9830 
   9831     if (!psource_frame->nFilledLen) {
   9832         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
   9833 
   9834         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9835             if (pdest_frame) {
   9836                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   9837                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9838                         h264_scratch.nFilledLen) {
   9839                     if(pdest_frame->nFilledLen == 0) {
   9840                         /* No residual frame from before, send whatever
   9841                          * we have left */
   9842                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9843                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   9844                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9845                         h264_scratch.nFilledLen = 0;
   9846                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   9847                     } else {
   9848                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9849                         if(!isNewFrame) {
   9850                             /* Have a residual frame, but we know that the
   9851                              * AU in this frame is belonging to whatever
   9852                              * frame we had left over.  So append it */
   9853                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9854                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9855                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9856                              h264_scratch.nFilledLen = 0;
   9857                              if (h264_last_au_ts != LLONG_MAX)
   9858                                  pdest_frame->nTimeStamp = h264_last_au_ts;
   9859                         } else {
   9860                             /* Completely new frame, let's just push what
   9861                              * we have now.  The resulting EBD would trigger
   9862                              * another push */
   9863                             generate_ebd = OMX_FALSE;
   9864                             pdest_frame->nTimeStamp = h264_last_au_ts;
   9865                             h264_last_au_ts = h264_scratch.nTimeStamp;
   9866                         }
   9867                     }
   9868                 } else {
   9869                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
   9870                     return OMX_ErrorBadParameter;
   9871                 }
   9872 
   9873                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   9874                 if(generate_ebd == OMX_TRUE) {
   9875                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9876                 }
   9877 
   9878                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
   9879                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9880                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
   9881 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9882                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9883                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   9884                     if (!VALID_TS(pdest_frame->nTimeStamp))
   9885                         pdest_frame->nTimeStamp = ts_in_sei;
   9886                 }
   9887 #endif
   9888                 /*Push the frame to the Decoder*/
   9889                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9890                     return OMX_ErrorBadParameter;
   9891                 }
   9892                 frame_count++;
   9893                 pdest_frame = NULL;
   9894             } else {
   9895                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9896                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9897                 generate_ebd = OMX_FALSE;
   9898             }
   9899         }
   9900     }
   9901     if (generate_ebd && !psource_frame->nFilledLen) {
   9902         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9903         psource_frame = NULL;
   9904         if (m_input_pending_q.m_size) {
   9905             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9906             m_input_pending_q.pop_entry(&address,&p2,&id);
   9907             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9908             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
   9909                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9910         }
   9911     }
   9912     return OMX_ErrorNone;
   9913 }
   9914 
   9915 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
   9916 {
   9917     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9918     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
   9919         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
   9920         if (pDst->nTimeStamp == LLONG_MAX) {
   9921             pDst->nTimeStamp = pSrc->nTimeStamp;
   9922             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
   9923         }
   9924         pDst->nFilledLen += pSrc->nFilledLen;
   9925         pSrc->nFilledLen = 0;
   9926     } else {
   9927         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
   9928         rc = OMX_ErrorBadParameter;
   9929     }
   9930     return rc;
   9931 }
   9932 
   9933 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
   9934 {
   9935     OMX_U32 partial_frame = 1;
   9936     unsigned long address,p2,id;
   9937     OMX_BOOL isNewFrame = OMX_FALSE;
   9938     OMX_BOOL generate_ebd = OMX_TRUE;
   9939     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9940     if (h264_scratch.pBuffer == NULL) {
   9941         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
   9942         return OMX_ErrorBadParameter;
   9943     }
   9944 
   9945     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
   9946             pdest_frame nFilledLen %u nTimeStamp %lld",
   9947             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9948 
   9949     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9950         look_ahead_nal = false;
   9951         rc = copy_buffer(pdest_frame, &h264_scratch);
   9952         if (rc != OMX_ErrorNone) {
   9953             return rc;
   9954         }
   9955     }
   9956 
   9957     if (nal_length == 0) {
   9958         if (m_frame_parser.parse_sc_frame(psource_frame,
   9959                     &h264_scratch,&partial_frame) == -1) {
   9960             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9961             return OMX_ErrorBadParameter;
   9962         }
   9963     } else {
   9964         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
   9965         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9966                     &h264_scratch,&partial_frame) == -1) {
   9967             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9968             return OMX_ErrorBadParameter;
   9969         }
   9970     }
   9971 
   9972     if (partial_frame == 0) {
   9973         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9974             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9975             nal_count++;
   9976             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9977             h264_scratch.nFlags = psource_frame->nFlags;
   9978         } else {
   9979             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
   9980             if (h264_scratch.nFilledLen) {
   9981                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
   9982                 nal_count++;
   9983             }
   9984 
   9985             if (!isNewFrame) {
   9986                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
   9987                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
   9988                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
   9989                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9990                 rc = copy_buffer(pdest_frame, &h264_scratch);
   9991                 if (rc != OMX_ErrorNone) {
   9992                     return rc;
   9993                 }
   9994             } else {
   9995                 look_ahead_nal = true;
   9996                 if (pdest_frame->nFilledLen == 0) {
   9997                     look_ahead_nal = false;
   9998                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
   9999                     rc = copy_buffer(pdest_frame, &h264_scratch);
   10000                     if (rc != OMX_ErrorNone) {
   10001                         return OMX_ErrorBadParameter;
   10002                     }
   10003                 } else {
   10004                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   10005                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   10006                     }
   10007                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
   10008                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
   10009                             nFilledLen %u nTimeStamp %lld",
   10010                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
   10011                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
   10012                             h264_scratch.nTimeStamp);
   10013                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   10014                         return OMX_ErrorBadParameter;
   10015                     }
   10016                     pdest_frame = NULL;
   10017                     if (m_input_free_q.m_size) {
   10018                         m_input_free_q.pop_entry(&address, &p2, &id);
   10019                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   10020                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
   10021                         pdest_frame->nFilledLen = 0;
   10022                         pdest_frame->nFlags = 0;
   10023                         pdest_frame->nTimeStamp = LLONG_MAX;
   10024                     }
   10025                 }
   10026             }
   10027         }
   10028     } else {
   10029         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
   10030                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
   10031                 nFilledLen %u nTimeStamp %lld",
   10032                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
   10033                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
   10034                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
   10035 
   10036         if (h264_scratch.nAllocLen ==
   10037                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   10038             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   10039             return OMX_ErrorStreamCorrupt;
   10040         }
   10041     }
   10042 
   10043     if (!psource_frame->nFilledLen) {
   10044         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
   10045         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   10046             if (pdest_frame) {
   10047                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   10048                 rc = copy_buffer(pdest_frame, &h264_scratch);
   10049                 if ( rc != OMX_ErrorNone ) {
   10050                     return rc;
   10051                 }
   10052                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   10053                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   10054                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
   10055                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   10056                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   10057                     return OMX_ErrorBadParameter;
   10058                 }
   10059                 frame_count++;
   10060                 pdest_frame = NULL;
   10061             } else {
   10062                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   10063                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   10064                 generate_ebd = OMX_FALSE;
   10065             }
   10066         }
   10067     }
   10068 
   10069     if (generate_ebd && !psource_frame->nFilledLen) {
   10070         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
   10071         psource_frame = NULL;
   10072         if (m_input_pending_q.m_size) {
   10073             m_input_pending_q.pop_entry(&address, &p2, &id);
   10074             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   10075             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
   10076                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
   10077         }
   10078     }
   10079     return OMX_ErrorNone;
   10080 }
   10081 
   10082 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp)
   10083 {
   10084     OMX_U8 *buf, *pdest;
   10085     OMX_U32 partial_frame = 1;
   10086     OMX_U32 buf_len, dest_len;
   10087 
   10088     if (first_frame == 0) {
   10089         first_frame = 1;
   10090         DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
   10091         if (!m_vendor_config.pData) {
   10092             DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
   10093             buf = psource_frame->pBuffer;
   10094             buf_len = psource_frame->nFilledLen;
   10095 
   10096             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   10097                     VC1_SP_MP_START_CODE) {
   10098                 m_vc1_profile = VC1_SP_MP_RCV;
   10099             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   10100                 m_vc1_profile = VC1_AP;
   10101             } else {
   10102                 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
   10103                 return OMX_ErrorStreamCorrupt;
   10104             }
   10105         } else {
   10106             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   10107                 pdest_frame->nOffset;
   10108             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   10109                     pdest_frame->nOffset);
   10110 
   10111             if (dest_len < m_vendor_config.nDataSize) {
   10112                 DEBUG_PRINT_ERROR("Destination buffer full");
   10113                 return OMX_ErrorBadParameter;
   10114             } else {
   10115                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   10116                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   10117             }
   10118         }
   10119     }
   10120 
   10121     switch (m_vc1_profile) {
   10122         case VC1_AP:
   10123             DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
   10124             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   10125                 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
   10126                 return OMX_ErrorBadParameter;
   10127             }
   10128             break;
   10129 
   10130         case VC1_SP_MP_RCV:
   10131         default:
   10132             DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
   10133             return OMX_ErrorBadParameter;
   10134     }
   10135     return OMX_ErrorNone;
   10136 }
   10137 
   10138 #ifndef USE_ION
   10139 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   10140         OMX_U32 alignment)
   10141 {
   10142     struct pmem_allocation allocation;
   10143     allocation.size = buffer_size;
   10144     allocation.align = clip2(alignment);
   10145     if (allocation.align < 4096) {
   10146         allocation.align = 4096;
   10147     }
   10148     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   10149         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
   10150                 allocation.align, allocation.size);
   10151         return false;
   10152     }
   10153     return true;
   10154 }
   10155 #endif
   10156 #ifdef USE_ION
   10157 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   10158         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   10159         struct ion_fd_data *fd_data, int flag)
   10160 {
   10161     int fd = -EINVAL;
   10162     int rc = -EINVAL;
   10163     int ion_dev_flag;
   10164     struct vdec_ion ion_buf_info;
   10165     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   10166         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
   10167         return -EINVAL;
   10168     }
   10169     ion_dev_flag = O_RDONLY;
   10170     fd = open (MEM_DEVICE, ion_dev_flag);
   10171     if (fd < 0) {
   10172         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
   10173         return fd;
   10174     }
   10175 
   10176     alloc_data->flags = flag;
   10177     alloc_data->len = buffer_size;
   10178     alloc_data->align = clip2(alignment);
   10179     if (alloc_data->align < 4096) {
   10180         alloc_data->align = 4096;
   10181     }
   10182 
   10183     alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   10184     if (secure_mode && (alloc_data->flags & ION_SECURE)) {
   10185         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   10186     }
   10187 
   10188     /* Use secure display cma heap for obvious reasons. */
   10189     if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
   10190         alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
   10191     }
   10192 
   10193     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   10194     if (rc || !alloc_data->handle) {
   10195         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
   10196         alloc_data->handle = 0;
   10197         close(fd);
   10198         fd = -ENOMEM;
   10199         return fd;
   10200     }
   10201     fd_data->handle = alloc_data->handle;
   10202     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   10203     if (rc) {
   10204         DEBUG_PRINT_ERROR("ION MAP failed ");
   10205         ion_buf_info.ion_alloc_data = *alloc_data;
   10206         ion_buf_info.ion_device_fd = fd;
   10207         ion_buf_info.fd_ion_data = *fd_data;
   10208         free_ion_memory(&ion_buf_info);
   10209         fd_data->fd =-1;
   10210         fd = -ENOMEM;
   10211     }
   10212 
   10213     return fd;
   10214 }
   10215 
   10216 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   10217 {
   10218 
   10219     if (!buf_ion_info) {
   10220         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
   10221         return;
   10222     }
   10223     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   10224                 &buf_ion_info->ion_alloc_data.handle)) {
   10225         DEBUG_PRINT_ERROR("ION: free failed" );
   10226     }
   10227     close(buf_ion_info->ion_device_fd);
   10228     buf_ion_info->ion_device_fd = -1;
   10229     buf_ion_info->ion_alloc_data.handle = 0;
   10230     buf_ion_info->fd_ion_data.fd = -1;
   10231 }
   10232 #endif
   10233 void omx_vdec::free_output_buffer_header()
   10234 {
   10235     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
   10236     output_use_buffer = false;
   10237     ouput_egl_buffers = false;
   10238 
   10239     if (m_out_mem_ptr) {
   10240         free (m_out_mem_ptr);
   10241         m_out_mem_ptr = NULL;
   10242     }
   10243 
   10244     if (m_platform_list) {
   10245         free(m_platform_list);
   10246         m_platform_list = NULL;
   10247     }
   10248 
   10249     if (drv_ctx.ptr_respbuffer) {
   10250         free (drv_ctx.ptr_respbuffer);
   10251         drv_ctx.ptr_respbuffer = NULL;
   10252     }
   10253     if (drv_ctx.ptr_outputbuffer) {
   10254         free (drv_ctx.ptr_outputbuffer);
   10255         drv_ctx.ptr_outputbuffer = NULL;
   10256     }
   10257 #ifdef USE_ION
   10258     if (drv_ctx.op_buf_ion_info) {
   10259         DEBUG_PRINT_LOW("Free o/p ion context");
   10260         free(drv_ctx.op_buf_ion_info);
   10261         drv_ctx.op_buf_ion_info = NULL;
   10262     }
   10263 #endif
   10264     free(drv_ctx.op_buf_map_info);
   10265     drv_ctx.op_buf_map_info = NULL;
   10266     buf_ref_remove();
   10267 }
   10268 
   10269 void omx_vdec::free_input_buffer_header()
   10270 {
   10271     input_use_buffer = false;
   10272     if (arbitrary_bytes) {
   10273         if (m_inp_heap_ptr) {
   10274             DEBUG_PRINT_LOW("Free input Heap Pointer");
   10275             free (m_inp_heap_ptr);
   10276             m_inp_heap_ptr = NULL;
   10277         }
   10278 
   10279         if (m_phdr_pmem_ptr) {
   10280             DEBUG_PRINT_LOW("Free input pmem header Pointer");
   10281             free (m_phdr_pmem_ptr);
   10282             m_phdr_pmem_ptr = NULL;
   10283         }
   10284     }
   10285     if (m_inp_mem_ptr) {
   10286         DEBUG_PRINT_LOW("Free input pmem Pointer area");
   10287         free (m_inp_mem_ptr);
   10288         m_inp_mem_ptr = NULL;
   10289     }
   10290     /* We just freed all the buffer headers, every thing in m_input_free_q,
   10291      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
   10292     while (m_input_free_q.m_size) {
   10293         unsigned long address, p2, id;
   10294         m_input_free_q.pop_entry(&address, &p2, &id);
   10295     }
   10296     while (m_input_pending_q.m_size) {
   10297         unsigned long address, p2, id;
   10298         m_input_pending_q.pop_entry(&address, &p2, &id);
   10299     }
   10300     pdest_frame = NULL;
   10301     psource_frame = NULL;
   10302     if (drv_ctx.ptr_inputbuffer) {
   10303         DEBUG_PRINT_LOW("Free Driver Context pointer");
   10304         free (drv_ctx.ptr_inputbuffer);
   10305         drv_ctx.ptr_inputbuffer = NULL;
   10306     }
   10307 #ifdef USE_ION
   10308     if (drv_ctx.ip_buf_ion_info) {
   10309         DEBUG_PRINT_LOW("Free ion context");
   10310         free(drv_ctx.ip_buf_ion_info);
   10311         drv_ctx.ip_buf_ion_info = NULL;
   10312     }
   10313 #endif
   10314 }
   10315 
   10316 void omx_vdec::free_output_extradata_buffer_header() {
   10317     client_extradata = false;
   10318     if (m_client_output_extradata_mem_ptr) {
   10319         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
   10320         free(m_client_output_extradata_mem_ptr);
   10321         m_client_output_extradata_mem_ptr = NULL;
   10322     }
   10323 }
   10324 
   10325 int omx_vdec::stream_off(OMX_U32 port)
   10326 {
   10327     enum v4l2_buf_type btype;
   10328     int rc = 0;
   10329     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   10330 
   10331     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   10332         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10333         v4l2_port = OUTPUT_PORT;
   10334     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   10335         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10336         v4l2_port = CAPTURE_PORT;
   10337     } else if (port == OMX_ALL) {
   10338         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   10339         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   10340 
   10341         if (!rc_input)
   10342             return rc_input;
   10343         else
   10344             return rc_output;
   10345     }
   10346 
   10347     if (!streaming[v4l2_port]) {
   10348         // already streamed off, warn and move on
   10349         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   10350                 " which is already streamed off", v4l2_port);
   10351         return 0;
   10352     }
   10353 
   10354     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   10355 
   10356     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   10357     if (rc) {
   10358         /*TODO: How to handle this case */
   10359         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
   10360     } else {
   10361         streaming[v4l2_port] = false;
   10362     }
   10363 
   10364     return rc;
   10365 }
   10366 
   10367 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   10368 {
   10369     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10370     struct v4l2_requestbuffers bufreq;
   10371     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
   10372     unsigned int final_extra_data_size = 0;
   10373     struct v4l2_format fmt;
   10374     int ret = 0;
   10375     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   10376             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10377     bufreq.memory = V4L2_MEMORY_USERPTR;
   10378     bufreq.count = 1;
   10379     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10380         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10381         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10382         fmt.fmt.pix_mp.pixelformat = output_capability;
   10383     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10384         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10385         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10386         fmt.fmt.pix_mp.pixelformat = capture_capability;
   10387     } else {
   10388         eRet = OMX_ErrorBadParameter;
   10389     }
   10390     if (eRet==OMX_ErrorNone) {
   10391         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10392     }
   10393     if (ret) {
   10394         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   10395         /*TODO: How to handle this case */
   10396         eRet = OMX_ErrorInsufficientResources;
   10397         return eRet;
   10398     } else {
   10399         bool is_res_1080p_or_below = (drv_ctx.video_resolution.frame_width <= 1920 &&
   10400                                      drv_ctx.video_resolution.frame_height <= 1088) ||
   10401                                      (drv_ctx.video_resolution.frame_height <= 1088 &&
   10402                                       drv_ctx.video_resolution.frame_width <= 1920);
   10403 
   10404         int fps = drv_ctx.frame_rate.fps_numerator / (float)drv_ctx.frame_rate.fps_denominator;
   10405         bool fps_above_180 =  (fps >= 180 || operating_frame_rate >= 180) ? true : false;
   10406         bool increase_output = (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) && (bufreq.count >= 16);
   10407 
   10408         if (increase_output && fps_above_180 &&
   10409             output_capability == V4L2_PIX_FMT_H264 &&
   10410             is_res_1080p_or_below) {
   10411             m_need_turbo |= TURBO_MODE_HIGH_FPS;
   10412             DEBUG_PRINT_LOW("High fps - fps = %d operating_rate = %d", fps, operating_frame_rate);
   10413             DEBUG_PRINT_LOW("getbufreq[output]: Increase buffer count (%d) to (%d) to support high fps",
   10414                             bufreq.count, bufreq.count + 10);
   10415             bufreq.count += 10;
   10416             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10417             if (ret) {
   10418                 DEBUG_PRINT_ERROR("(Failed to set updated buffer count to driver");
   10419                 eRet = OMX_ErrorInsufficientResources;
   10420                 return eRet;
   10421             }
   10422             DEBUG_PRINT_LOW("new buf count = %d set to driver", bufreq.count);
   10423             request_perf_level(VIDC_TURBO);
   10424         }
   10425 
   10426         buffer_prop->actualcount = bufreq.count;
   10427         buffer_prop->mincount = bufreq.count;
   10428         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
   10429     }
   10430     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   10431             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10432 
   10433     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10434 
   10435     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   10436         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   10437     DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   10438 
   10439     if (ret) {
   10440         /*TODO: How to handle this case */
   10441         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   10442         eRet = OMX_ErrorInsufficientResources;
   10443     } else {
   10444         int extra_idx = 0;
   10445 
   10446         eRet = is_video_session_supported();
   10447         if (eRet)
   10448             return eRet;
   10449 
   10450         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   10451         buf_size = buffer_prop->buffer_size;
   10452         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   10453         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   10454             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   10455         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   10456             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   10457             return OMX_ErrorBadParameter;
   10458         }
   10459 
   10460         default_extra_data_size = VENUS_EXTRADATA_SIZE(
   10461                 drv_ctx.video_resolution.frame_height,
   10462                 drv_ctx.video_resolution.frame_width);
   10463         final_extra_data_size = extra_data_size > default_extra_data_size ?
   10464             extra_data_size : default_extra_data_size;
   10465 
   10466         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
   10467             (~(buffer_prop->alignment - 1));
   10468 
   10469         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
   10470         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   10471         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
   10472         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   10473         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
   10474                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
   10475         if (extra_data_size)
   10476             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
   10477                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
   10478 
   10479         if (in_reconfig) // BufReq will be set to driver when port is disabled
   10480             buffer_prop->buffer_size = buf_size;
   10481         else if (buf_size != buffer_prop->buffer_size) {
   10482             buffer_prop->buffer_size = buf_size;
   10483             eRet = set_buffer_req(buffer_prop);
   10484         }
   10485     }
   10486     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
   10487             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10488     return eRet;
   10489 }
   10490 
   10491 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   10492 {
   10493     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10494     unsigned buf_size = 0;
   10495     struct v4l2_format fmt, c_fmt;
   10496     struct v4l2_requestbuffers bufreq;
   10497     int ret = 0;
   10498     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
   10499             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   10500     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   10501     if (buf_size != buffer_prop->buffer_size) {
   10502         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
   10503                 (unsigned int)buffer_prop->buffer_size, buf_size);
   10504         eRet = OMX_ErrorBadParameter;
   10505     } else {
   10506         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   10507         memset(&c_fmt, 0x0, sizeof(struct v4l2_format));
   10508         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   10509         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   10510         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   10511 
   10512         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10513             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10514             fmt.fmt.pix_mp.pixelformat = output_capability;
   10515             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10516         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10517             c_fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10518             c_fmt.fmt.pix_mp.pixelformat = capture_capability;
   10519             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &c_fmt);
   10520             c_fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   10521             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &c_fmt);
   10522         } else {
   10523             eRet = OMX_ErrorBadParameter;
   10524         }
   10525 
   10526         if (ret) {
   10527             /*TODO: How to handle this case */
   10528             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   10529             eRet = OMX_ErrorInsufficientResources;
   10530         }
   10531 
   10532         bufreq.memory = V4L2_MEMORY_USERPTR;
   10533         bufreq.count = buffer_prop->actualcount;
   10534         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   10535             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10536         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   10537             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10538         } else {
   10539             eRet = OMX_ErrorBadParameter;
   10540         }
   10541 
   10542         if (eRet==OMX_ErrorNone) {
   10543             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   10544         }
   10545 
   10546         if (ret) {
   10547             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   10548             /*TODO: How to handle this case */
   10549             eRet = OMX_ErrorInsufficientResources;
   10550         } else if (bufreq.count < buffer_prop->actualcount) {
   10551             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   10552                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   10553                     buffer_prop->actualcount, bufreq.count);
   10554             eRet = OMX_ErrorInsufficientResources;
   10555         } else {
   10556             if (!client_buffers.update_buffer_req()) {
   10557                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   10558                 eRet = OMX_ErrorInsufficientResources;
   10559             }
   10560         }
   10561     }
   10562     return eRet;
   10563 }
   10564 
   10565 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   10566 {
   10567     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10568     return eRet;
   10569 }
   10570 
   10571 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   10572 {
   10573     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10574     struct v4l2_format fmt;
   10575     if (!portDefn) {
   10576         return OMX_ErrorBadParameter;
   10577     }
   10578     DEBUG_PRINT_LOW("omx_vdec::update_portdef");
   10579     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   10580     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   10581     portDefn->eDomain    = OMX_PortDomainVideo;
   10582     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   10583     if (0 == portDefn->nPortIndex) {
   10584         portDefn->eDir =  OMX_DirInput;
   10585         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   10586         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   10587         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   10588         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   10589         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   10590         //for input port, always report the fps value set by client,
   10591         //to distinguish whether client got valid fps from parser.
   10592         portDefn->format.video.xFramerate = m_fps_received;
   10593         portDefn->bEnabled   = m_inp_bEnabled;
   10594         portDefn->bPopulated = m_inp_bPopulated;
   10595 
   10596         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10597         fmt.fmt.pix_mp.pixelformat = output_capability;
   10598         ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10599     } else if (1 == portDefn->nPortIndex) {
   10600         unsigned int buf_size = 0;
   10601         int ret = 0;
   10602        if (in_reconfig && !is_down_scalar_enabled) {
   10603            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10604            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10605            fmt.fmt.pix_mp.pixelformat = capture_capability;
   10606            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10607            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10608        }
   10609 
   10610        fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10611        fmt.fmt.pix_mp.pixelformat = capture_capability;
   10612        ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   10613        if (ret) {
   10614            DEBUG_PRINT_ERROR("Get Resolution failed");
   10615            return OMX_ErrorHardware;
   10616        }
   10617        drv_ctx.op_buf.buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   10618        if (!client_buffers.update_buffer_req()) {
   10619            DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
   10620            return OMX_ErrorHardware;
   10621        }
   10622 
   10623         if (!client_buffers.get_buffer_req(buf_size)) {
   10624             DEBUG_PRINT_ERROR("update buffer requirements");
   10625             return OMX_ErrorHardware;
   10626         }
   10627         portDefn->nBufferSize = buf_size;
   10628         portDefn->eDir =  OMX_DirOutput;
   10629         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   10630         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   10631         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   10632         if (drv_ctx.frame_rate.fps_denominator > 0)
   10633             portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
   10634                 drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
   10635         else {
   10636             DEBUG_PRINT_ERROR("Error: Divide by zero");
   10637             return OMX_ErrorBadParameter;
   10638         }
   10639         portDefn->bEnabled   = m_out_bEnabled;
   10640         portDefn->bPopulated = m_out_bPopulated;
   10641         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   10642             DEBUG_PRINT_ERROR("Error in getting color format");
   10643             return OMX_ErrorHardware;
   10644         }
   10645         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   10646         fmt.fmt.pix_mp.pixelformat = capture_capability;
   10647     } else if (OMX_CORE_OUTPUT_EXTRADATA_INDEX == portDefn->nPortIndex) {
   10648         portDefn->nBufferSize = m_client_out_extradata_info.getSize();
   10649         portDefn->nBufferCountMin = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
   10650         portDefn->nBufferCountActual = MIN_NUM_INPUT_OUTPUT_EXTRADATA_BUFFERS;
   10651         portDefn->eDir =  OMX_DirOutput;
   10652     } else {
   10653         portDefn->eDir = OMX_DirMax;
   10654         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   10655                 (int)portDefn->nPortIndex);
   10656         eRet = OMX_ErrorBadPortIndex;
   10657     }
   10658     update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
   10659         fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   10660 
   10661         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   10662         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   10663         portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   10664         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   10665 
   10666     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
   10667        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
   10668            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
   10669            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
   10670     }
   10671     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
   10672             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
   10673             (unsigned int)portDefn->nPortIndex,
   10674             (unsigned int)portDefn->format.video.nFrameWidth,
   10675             (unsigned int)portDefn->format.video.nFrameHeight,
   10676             (int)portDefn->format.video.nStride,
   10677             (unsigned int)portDefn->format.video.nSliceHeight,
   10678             (unsigned int)portDefn->format.video.eColorFormat,
   10679             (unsigned int)portDefn->nBufferSize,
   10680             (unsigned int)portDefn->nBufferCountActual);
   10681 
   10682     return eRet;
   10683 }
   10684 
   10685 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   10686 {
   10687     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10688     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   10689     unsigned i = 0;
   10690 
   10691     if (!m_out_mem_ptr) {
   10692         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
   10693         int nBufHdrSize        = 0;
   10694         int nPlatformEntrySize = 0;
   10695         int nPlatformListSize  = 0;
   10696         int nPMEMInfoSize = 0;
   10697         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   10698         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   10699         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   10700 
   10701         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
   10702                 drv_ctx.op_buf.actualcount);
   10703         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   10704             sizeof(OMX_BUFFERHEADERTYPE);
   10705 
   10706         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   10707             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   10708         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   10709             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   10710         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   10711             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   10712 
   10713         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   10714                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   10715                 nPMEMInfoSize,
   10716                 nPlatformListSize);
   10717         DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
   10718                 m_out_bm_count);
   10719         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   10720         // Alloc mem for platform specific info
   10721         char *pPtr=NULL;
   10722         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   10723                 nPMEMInfoSize,1);
   10724         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   10725                        calloc (sizeof(struct vdec_bufferpayload),
   10726                                drv_ctx.op_buf.actualcount);
   10727         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   10728                      calloc (sizeof (struct vdec_output_frameinfo),
   10729                              drv_ctx.op_buf.actualcount);
   10730         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   10731             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
   10732             return OMX_ErrorInsufficientResources;
   10733         }
   10734 
   10735 #ifdef USE_ION
   10736         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   10737                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   10738         if (!drv_ctx.op_buf_ion_info) {
   10739             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   10740             return OMX_ErrorInsufficientResources;
   10741         }
   10742 #endif
   10743         if (dynamic_buf_mode) {
   10744             out_dynamic_list = (struct dynamic_buf_list *) \
   10745                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   10746             if (out_dynamic_list) {
   10747                for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++)
   10748                   out_dynamic_list[i].dup_fd = -1;
   10749             }
   10750         }
   10751 
   10752         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   10753                 && drv_ctx.ptr_respbuffer) {
   10754             bufHdr          =  m_out_mem_ptr;
   10755             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   10756             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   10757                 (((char *) m_platform_list)  + nPlatformListSize);
   10758             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   10759                 (((char *) m_platform_entry) + nPlatformEntrySize);
   10760             pPlatformList   = m_platform_list;
   10761             pPlatformEntry  = m_platform_entry;
   10762             pPMEMInfo       = m_pmem_info;
   10763 
   10764             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   10765 
   10766             // Settting the entire storage nicely
   10767             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
   10768                     m_out_mem_ptr,pPlatformEntry);
   10769             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   10770             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   10771                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   10772                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   10773                 // Set the values when we determine the right HxW param
   10774                 bufHdr->nAllocLen          = 0;
   10775                 bufHdr->nFilledLen         = 0;
   10776                 bufHdr->pAppPrivate        = NULL;
   10777                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   10778                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   10779                 pPlatformEntry->entry      = pPMEMInfo;
   10780                 // Initialize the Platform List
   10781                 pPlatformList->nEntries    = 1;
   10782                 pPlatformList->entryList   = pPlatformEntry;
   10783                 // Keep pBuffer NULL till vdec is opened
   10784                 bufHdr->pBuffer            = NULL;
   10785                 pPMEMInfo->offset          =  0;
   10786                 pPMEMInfo->pmem_fd = -1;
   10787                 bufHdr->pPlatformPrivate = pPlatformList;
   10788                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   10789 #ifdef USE_ION
   10790                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   10791 #endif
   10792                 /*Create a mapping between buffers*/
   10793                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   10794                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   10795                                     &drv_ctx.ptr_outputbuffer[i];
   10796                 // Move the buffer and buffer header pointers
   10797                 bufHdr++;
   10798                 pPMEMInfo++;
   10799                 pPlatformEntry++;
   10800                 pPlatformList++;
   10801             }
   10802         } else {
   10803             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   10804                     m_out_mem_ptr, pPtr);
   10805             if (m_out_mem_ptr) {
   10806                 free(m_out_mem_ptr);
   10807                 m_out_mem_ptr = NULL;
   10808             }
   10809             if (pPtr) {
   10810                 free(pPtr);
   10811                 pPtr = NULL;
   10812             }
   10813             if (drv_ctx.ptr_outputbuffer) {
   10814                 free(drv_ctx.ptr_outputbuffer);
   10815                 drv_ctx.ptr_outputbuffer = NULL;
   10816             }
   10817             if (drv_ctx.ptr_respbuffer) {
   10818                 free(drv_ctx.ptr_respbuffer);
   10819                 drv_ctx.ptr_respbuffer = NULL;
   10820             }
   10821 #ifdef USE_ION
   10822             if (drv_ctx.op_buf_ion_info) {
   10823                 DEBUG_PRINT_LOW("Free o/p ion context");
   10824                 free(drv_ctx.op_buf_ion_info);
   10825                 drv_ctx.op_buf_ion_info = NULL;
   10826             }
   10827 #endif
   10828             free(drv_ctx.op_buf_map_info);
   10829             drv_ctx.op_buf_map_info = NULL;
   10830             eRet =  OMX_ErrorInsufficientResources;
   10831         }
   10832     } else {
   10833         eRet =  OMX_ErrorInsufficientResources;
   10834     }
   10835     return eRet;
   10836 }
   10837 
   10838 void omx_vdec::complete_pending_buffer_done_cbs()
   10839 {
   10840     unsigned long p1, p2, ident;
   10841     omx_cmd_queue tmp_q, pending_bd_q;
   10842     pthread_mutex_lock(&m_lock);
   10843     // pop all pending GENERATE FDB from ftb queue
   10844     while (m_ftb_q.m_size) {
   10845         m_ftb_q.pop_entry(&p1,&p2,&ident);
   10846         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   10847             pending_bd_q.insert_entry(p1,p2,ident);
   10848         } else {
   10849             tmp_q.insert_entry(p1,p2,ident);
   10850         }
   10851     }
   10852     //return all non GENERATE FDB to ftb queue
   10853     while (tmp_q.m_size) {
   10854         tmp_q.pop_entry(&p1,&p2,&ident);
   10855         m_ftb_q.insert_entry(p1,p2,ident);
   10856     }
   10857     // pop all pending GENERATE EDB from etb queue
   10858     while (m_etb_q.m_size) {
   10859         m_etb_q.pop_entry(&p1,&p2,&ident);
   10860         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   10861             pending_bd_q.insert_entry(p1,p2,ident);
   10862         } else {
   10863             tmp_q.insert_entry(p1,p2,ident);
   10864         }
   10865     }
   10866     //return all non GENERATE FDB to etb queue
   10867     while (tmp_q.m_size) {
   10868         tmp_q.pop_entry(&p1,&p2,&ident);
   10869         m_etb_q.insert_entry(p1,p2,ident);
   10870     }
   10871     pthread_mutex_unlock(&m_lock);
   10872     // process all pending buffer dones
   10873     while (pending_bd_q.m_size) {
   10874         pending_bd_q.pop_entry(&p1,&p2,&ident);
   10875         switch (ident) {
   10876             case OMX_COMPONENT_GENERATE_EBD:
   10877                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   10878                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   10879                     omx_report_error ();
   10880                 }
   10881                 break;
   10882 
   10883             case OMX_COMPONENT_GENERATE_FBD:
   10884                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   10885                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   10886                     omx_report_error ();
   10887                 }
   10888                 break;
   10889         }
   10890     }
   10891 }
   10892 
   10893 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   10894 {
   10895     OMX_U32 new_frame_interval = 0;
   10896     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   10897             && llabs(act_timestamp - prev_ts) > 2000) {
   10898         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
   10899             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
   10900         if (new_frame_interval != frm_int || frm_int == 0) {
   10901             frm_int = new_frame_interval;
   10902             if (frm_int) {
   10903                 drv_ctx.frame_rate.fps_numerator = 1e6;
   10904                 drv_ctx.frame_rate.fps_denominator = frm_int;
   10905                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
   10906                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   10907                         (float)drv_ctx.frame_rate.fps_denominator);
   10908                 m_perf_control.request_cores(frm_int);
   10909                 /* We need to report the difference between this FBD and the previous FBD
   10910                  * back to the driver for clock scaling purposes. */
   10911                 struct v4l2_outputparm oparm;
   10912                 /*XXX: we're providing timing info as seconds per frame rather than frames
   10913                  * per second.*/
   10914                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   10915                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   10916 
   10917                 struct v4l2_streamparm sparm;
   10918                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10919                 sparm.parm.output = oparm;
   10920                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   10921                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   10922                             performance might be affected");
   10923                 }
   10924 
   10925             }
   10926         }
   10927     }
   10928     prev_ts = act_timestamp;
   10929 }
   10930 
   10931 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   10932 {
   10933     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   10934         prev_ts = act_timestamp;
   10935         prev_ts_actual = act_timestamp;
   10936         rst_prev_ts = false;
   10937     } else if (VALID_TS(prev_ts)) {
   10938         bool codec_cond = (drv_ctx.timestamp_adjust)?
   10939             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
   10940             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
   10941              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
   10942         if (frm_int > 0 && codec_cond) {
   10943             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   10944             act_timestamp = prev_ts + frm_int;
   10945             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   10946             prev_ts = act_timestamp;
   10947         } else {
   10948             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
   10949                 // ensure that timestamps can never step backwards when in display order
   10950                 act_timestamp = prev_ts;
   10951             }
   10952             set_frame_rate(act_timestamp);
   10953         }
   10954     } else if (frm_int > 0)          // In this case the frame rate was set along
   10955     {                               // with the port definition, start ts with 0
   10956         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   10957         rst_prev_ts = true;
   10958     }
   10959 }
   10960 
   10961 OMX_BUFFERHEADERTYPE* omx_vdec::get_omx_output_buffer_header(int index)
   10962 {
   10963     return m_out_mem_ptr + index;
   10964 }
   10965 
   10966 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
   10967     OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects)
   10968 {
   10969     switch (primaries) {
   10970         case MSM_VIDC_BT709_5:
   10971             *color_space = ITU_R_709;
   10972             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
   10973             break;
   10974         case MSM_VIDC_BT470_6_M:
   10975             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
   10976             break;
   10977         case MSM_VIDC_BT601_6_625:
   10978             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10979             break;
   10980         case MSM_VIDC_BT601_6_525:
   10981             *color_space = range ? ITU_R_601_FR : ITU_R_601;
   10982             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   10983             break;
   10984         case MSM_VIDC_GENERIC_FILM:
   10985             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
   10986             break;
   10987         case MSM_VIDC_BT2020:
   10988             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   10989             break;
   10990         case MSM_VIDC_UNSPECIFIED:
   10991             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
   10992         default:
   10993             //aspects->mPrimaries = ColorAspects::PrimariesOther;
   10994             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10995             break;
   10996     }
   10997 
   10998     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
   10999 
   11000     switch (transfer) {
   11001         case MSM_VIDC_TRANSFER_BT709_5:
   11002         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
   11003             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11004             break;
   11005         case MSM_VIDC_TRANSFER_BT_470_6_M:
   11006             aspects->mTransfer = ColorAspects::TransferGamma22;
   11007             break;
   11008         case MSM_VIDC_TRANSFER_BT_470_6_BG:
   11009             aspects->mTransfer = ColorAspects::TransferGamma28;
   11010             break;
   11011         case MSM_VIDC_TRANSFER_SMPTE_240M:
   11012             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   11013             break;
   11014         case MSM_VIDC_TRANSFER_LINEAR:
   11015             aspects->mTransfer = ColorAspects::TransferLinear;
   11016             break;
   11017         case MSM_VIDC_TRANSFER_IEC_61966:
   11018             aspects->mTransfer = ColorAspects::TransferXvYCC;
   11019             break;
   11020         case MSM_VIDC_TRANSFER_BT_1361:
   11021             aspects->mTransfer = ColorAspects::TransferBT1361;
   11022             break;
   11023         case MSM_VIDC_TRANSFER_SRGB:
   11024             aspects->mTransfer = ColorAspects::TransferSRGB;
   11025             break;
   11026         default:
   11027             //aspects->mTransfer = ColorAspects::TransferOther;
   11028             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
   11029             break;
   11030     }
   11031 
   11032     switch (matrix) {
   11033         case MSM_VIDC_MATRIX_BT_709_5:
   11034             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11035             break;
   11036         case MSM_VIDC_MATRIX_FCC_47:
   11037             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
   11038             break;
   11039         case MSM_VIDC_MATRIX_601_6_625:
   11040         case MSM_VIDC_MATRIX_601_6_525:
   11041             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   11042             break;
   11043         case MSM_VIDC_MATRIX_SMPTE_240M:
   11044             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
   11045             break;
   11046         case MSM_VIDC_MATRIX_BT_2020:
   11047             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   11048             break;
   11049         case MSM_VIDC_MATRIX_BT_2020_CONST:
   11050             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
   11051             break;
   11052         default:
   11053             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   11054             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   11055             break;
   11056     }
   11057 }
   11058 
   11059 void omx_vdec::print_debug_color_aspects(ColorAspects *a, const char *prefix) {
   11060         DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d(%s) Range = %d(%s) Tx = %d(%s) Matrix = %d(%s)",
   11061                 prefix, a->mPrimaries, asString(a->mPrimaries), a->mRange, asString(a->mRange),
   11062                 a->mTransfer, asString(a->mTransfer), a->mMatrixCoeffs, asString(a->mMatrixCoeffs));
   11063 }
   11064 
   11065 void omx_vdec::prepare_color_aspects_metadata(OMX_U32 primaries, OMX_U32 range,
   11066                                               OMX_U32 transfer, OMX_U32 matrix,
   11067                                               ColorMetaData *color_mdata)
   11068 {
   11069 
   11070     /* ColorAspects in qdMetaData */
   11071     color_mdata->colorPrimaries = (enum ColorPrimaries) primaries;
   11072     color_mdata->range = (enum ColorRange)range;
   11073     color_mdata->transfer = (enum GammaTransfer)transfer;
   11074     color_mdata->matrixCoefficients = (enum MatrixCoEfficients)matrix;
   11075 }
   11076 
   11077 bool omx_vdec::handle_color_space_info(void *data,
   11078                                        ColorSpace_t *color_space,
   11079                                        ColorMetaData *color_mdata,
   11080                                        bool& set_color_aspects_only)
   11081 {
   11082     ColorAspects tempAspects;
   11083     memset(&tempAspects, 0x0, sizeof(ColorAspects));
   11084     ColorAspects *aspects = &tempAspects;
   11085 
   11086     /* Set default ColorAspects */
   11087     prepare_color_aspects_metadata(ColorPrimaries_BT601_6_625, Range_Full,
   11088                                            Transfer_SMPTE_170M, MatrixCoEff_BT601_6_625,
   11089                                            color_mdata);
   11090 
   11091     switch(output_capability) {
   11092         case V4L2_PIX_FMT_MPEG2:
   11093             {
   11094                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   11095                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
   11096 
   11097                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
   11098                  * understand this code */
   11099 
   11100                 if (seqdisp_payload && seqdisp_payload->color_descp) {
   11101 
   11102                     convert_color_space_info(seqdisp_payload->color_primaries, 1,
   11103                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   11104                             color_space,aspects);
   11105                     m_disp_hor_size = seqdisp_payload->disp_width;
   11106                     m_disp_vert_size = seqdisp_payload->disp_height;
   11107                     set_color_aspects_only = true;
   11108                     prepare_color_aspects_metadata(seqdisp_payload->color_primaries, 1,
   11109                                                     seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   11110                                                     color_mdata);
   11111                 }
   11112             }
   11113             break;
   11114         case V4L2_PIX_FMT_H264:
   11115         case V4L2_PIX_FMT_HEVC:
   11116             {
   11117                 struct msm_vidc_vui_display_info_payload *display_info_payload;
   11118                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
   11119 
   11120                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
   11121 
   11122                 if (display_info_payload->video_signal_present_flag &&
   11123                         display_info_payload->color_description_present_flag) {
   11124                     convert_color_space_info(display_info_payload->color_primaries,
   11125                             display_info_payload->video_full_range_flag,
   11126                             display_info_payload->transfer_characteristics,
   11127                             display_info_payload->matrix_coefficients,
   11128                             color_space,aspects);
   11129                     set_color_aspects_only = true;
   11130                     prepare_color_aspects_metadata(display_info_payload->color_primaries,
   11131                                                    display_info_payload->video_full_range_flag,
   11132                                                    display_info_payload->transfer_characteristics,
   11133                                                    display_info_payload->matrix_coefficients,
   11134                                                    color_mdata);
   11135                 }
   11136             }
   11137             break;
   11138         case V4L2_PIX_FMT_VC1_ANNEX_G:
   11139         case V4L2_PIX_FMT_VC1_ANNEX_L:
   11140             {
   11141                 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload;
   11142                 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data;
   11143 
   11144                 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23
   11145                  * SMPTE 421M to understand this code */
   11146 
   11147                 if (m_enable_android_native_buffers &&
   11148                         vc1_seq_disp_payload->color_primaries) {
   11149 
   11150                     convert_color_space_info(vc1_seq_disp_payload->color_primaries,
   11151                             1,
   11152                             vc1_seq_disp_payload->transfer_char,
   11153                             vc1_seq_disp_payload->matrix_coeffs,
   11154                             color_space,aspects);
   11155                     set_color_aspects_only = true;
   11156                     prepare_color_aspects_metadata(vc1_seq_disp_payload->color_primaries,
   11157                                                    1,
   11158                                                    vc1_seq_disp_payload->transfer_char,
   11159                                                    vc1_seq_disp_payload->matrix_coeffs,
   11160                                                    color_mdata);
   11161                 }
   11162             }
   11163             break;
   11164         case V4L2_PIX_FMT_VP8:
   11165             {
   11166                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   11167                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   11168                 set_color_aspects_only = false;
   11169                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
   11170                  * to understand this code */
   11171 
   11172                 if (vpx_color_space_payload->color_space == 0) {
   11173                     *color_space = ITU_R_601;
   11174                     aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   11175                     aspects->mRange = ColorAspects::RangeLimited;
   11176                 } else {
   11177                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
   11178                     break;
   11179                 }
   11180             }
   11181             break;
   11182         case V4L2_PIX_FMT_VP9:
   11183             {
   11184                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   11185                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   11186                 set_color_aspects_only = false;
   11187                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
   11188                  * to understand this code */
   11189 
   11190                 switch(vpx_color_space_payload->color_space) {
   11191                     case MSM_VIDC_CS_BT_601:
   11192                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   11193                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11194                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   11195                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11196                         break;
   11197                     case MSM_VIDC_CS_BT_709:
   11198                         *color_space = ITU_R_709;
   11199                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11200                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11201                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
   11202                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11203                         break;
   11204                     case MSM_VIDC_CS_SMPTE_170:
   11205                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11206                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11207                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   11208                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11209                         break;
   11210                     case MSM_VIDC_CS_SMPTE_240:
   11211                         aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   11212                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   11213                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   11214                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11215                         break;
   11216                     case MSM_VIDC_CS_BT_2020:
   11217                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   11218                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
   11219                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   11220                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11221                         break;
   11222                     case MSM_VIDC_CS_RESERVED:
   11223                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   11224                         aspects->mTransfer = ColorAspects::TransferOther;
   11225                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   11226                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11227                         break;
   11228                     case MSM_VIDC_CS_RGB:
   11229                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   11230                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   11231                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   11232                         aspects->mRange = m_client_color_space.sAspects.mRange;
   11233                         break;
   11234                     default:
   11235                         break;
   11236                 }
   11237             }
   11238             break;
   11239         default:
   11240             break;
   11241     }
   11242 
   11243     print_debug_color_aspects(aspects, "Bitstream");
   11244 
   11245     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
   11246             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
   11247             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
   11248             m_internal_color_space.sAspects.mRange != aspects->mRange) {
   11249         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
   11250 
   11251         m_color_mdata.colorPrimaries = color_mdata->colorPrimaries;
   11252         m_color_mdata.range = color_mdata->range;
   11253         m_color_mdata.transfer = color_mdata->transfer;
   11254         m_color_mdata.matrixCoefficients = color_mdata->matrixCoefficients;
   11255 
   11256         DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to Color Aspects Change");
   11257         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
   11258         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
   11259 
   11260         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   11261                 OMX_QTIIndexConfigDescribeColorAspects,
   11262                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   11263         return true;
   11264     }
   11265     return false;
   11266 }
   11267 
   11268 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
   11269     private_handle_t *private_handle = NULL;
   11270     if (buf_index < drv_ctx.op_buf.actualcount &&
   11271             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   11272             native_buffer[buf_index].privatehandle) {
   11273         private_handle = native_buffer[buf_index].privatehandle;
   11274     }
   11275     if (private_handle) {
   11276         setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
   11277     }
   11278 }
   11279 
   11280 void omx_vdec::print_debug_hdr_color_info(HDRStaticInfo *hdr_info, const char *prefix)
   11281 {
   11282     if (!hdr_info->mID) {
   11283         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mR.x = %d mR.y = %d", prefix,
   11284                          hdr_info->sType1.mR.x, hdr_info->sType1.mR.y);
   11285         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mG.x = %d mG.y = %d", prefix,
   11286                          hdr_info->sType1.mG.x, hdr_info->sType1.mG.y);
   11287         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mB.x = %d mB.y = %d", prefix,
   11288                          hdr_info->sType1.mB.x, hdr_info->sType1.mB.y);
   11289         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: mW.x = %d mW.y = %d", prefix,
   11290                          hdr_info->sType1.mW.x, hdr_info->sType1.mW.y);
   11291         DEBUG_PRINT_LOW("%s : HDRstaticinfo MDC: maxDispLum = %d minDispLum = %d", prefix,
   11292                          hdr_info->sType1.mMaxDisplayLuminance, hdr_info->sType1.mMinDisplayLuminance);
   11293         DEBUG_PRINT_LOW("%s : HDRstaticinfo CLL: CLL = %d FLL = %d", prefix,
   11294                         hdr_info->sType1.mMaxContentLightLevel, hdr_info->sType1.mMaxFrameAverageLightLevel);
   11295     }
   11296 
   11297 }
   11298 
   11299 void omx_vdec::print_debug_hdr_color_info_mdata(ColorMetaData* color_mdata)
   11300 {
   11301     DEBUG_PRINT_LOW("setMetaData COLOR_METADATA : color_primaries = %u, range = %u, transfer = %u, matrix = %u",
   11302                     color_mdata->colorPrimaries, color_mdata->range,
   11303                     color_mdata->transfer, color_mdata->matrixCoefficients);
   11304 
   11305     for(uint8_t i = 0; i < 3; i++) {
   11306         for(uint8_t j = 0; j < 2; j++) {
   11307             DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : rgbPrimaries[%d][%d] = %d", i, j, color_mdata->masteringDisplayInfo.primaries.rgbPrimaries[i][j]);
   11308         }
   11309     }
   11310 
   11311     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : whitepoint[0] = %d whitepoint[1] = %d",
   11312                     color_mdata->masteringDisplayInfo.primaries.whitePoint[0],
   11313                     color_mdata->masteringDisplayInfo.primaries.whitePoint[1]);
   11314 
   11315     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxDispLum = %d minDispLum = %d",
   11316                     color_mdata->masteringDisplayInfo.maxDisplayLuminance,
   11317                     color_mdata->masteringDisplayInfo.minDisplayLuminance);
   11318 
   11319     DEBUG_PRINT_LOW("setMetadata COLOR_METADATA : maxCLL = %d maxFLL = %d",
   11320                     color_mdata->contentLightLevel.maxContentLightLevel,
   11321                     color_mdata->contentLightLevel.minPicAverageLightLevel);
   11322 
   11323 
   11324 }
   11325 
   11326 bool omx_vdec::handle_content_light_level_info(void* data, ContentLightLevel* light_level_mdata)
   11327 {
   11328     struct msm_vidc_content_light_level_sei_payload *light_level_payload =
   11329         (msm_vidc_content_light_level_sei_payload*)(data);
   11330 
   11331     light_level_mdata->lightLevelSEIEnabled = true;
   11332     light_level_mdata->maxContentLightLevel = light_level_payload->nMaxContentLight;
   11333     light_level_mdata->minPicAverageLightLevel = light_level_payload->nMaxPicAverageLight;
   11334 
   11335     if ((m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel != light_level_payload->nMaxContentLight) ||
   11336         (m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel != light_level_payload->nMaxPicAverageLight)) {
   11337         m_internal_hdr_info.sInfo.sType1.mMaxContentLightLevel = light_level_payload->nMaxContentLight;
   11338         m_internal_hdr_info.sInfo.sType1.mMaxFrameAverageLightLevel = light_level_payload->nMaxPicAverageLight;
   11339         return true;
   11340     }
   11341     return false;
   11342 }
   11343 
   11344 bool omx_vdec::handle_mastering_display_color_info(void* data, MasteringDisplay* mastering_display_mdata)
   11345 {
   11346     struct msm_vidc_mastering_display_colour_sei_payload *mastering_display_payload =
   11347         (msm_vidc_mastering_display_colour_sei_payload*)(data);
   11348     HDRStaticInfo* hdr_info = &m_internal_hdr_info.sInfo;
   11349     bool internal_disp_changed_flag = false;
   11350 
   11351     mastering_display_mdata->colorVolumeSEIEnabled = true;
   11352     for (uint8_t i = 0; i < 3; i++) {
   11353         mastering_display_mdata->primaries.rgbPrimaries[i][0] = mastering_display_payload->nDisplayPrimariesX[i];
   11354         mastering_display_mdata->primaries.rgbPrimaries[i][1] = mastering_display_payload->nDisplayPrimariesY[i];
   11355     }
   11356     mastering_display_mdata->primaries.whitePoint[0] = mastering_display_payload->nWhitePointX;
   11357     mastering_display_mdata->primaries.whitePoint[1] = mastering_display_payload->nWhitePointY;
   11358     mastering_display_mdata->maxDisplayLuminance = mastering_display_payload->nMaxDisplayMasteringLuminance;
   11359     mastering_display_mdata->minDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
   11360 
   11361     internal_disp_changed_flag |= (hdr_info->sType1.mR.x != mastering_display_payload->nDisplayPrimariesX[0]) ||
   11362         (hdr_info->sType1.mR.y != mastering_display_payload->nDisplayPrimariesY[0]);
   11363     internal_disp_changed_flag |= (hdr_info->sType1.mG.x != mastering_display_payload->nDisplayPrimariesX[1]) ||
   11364         (hdr_info->sType1.mG.y != mastering_display_payload->nDisplayPrimariesY[1]);
   11365     internal_disp_changed_flag |= (hdr_info->sType1.mB.x != mastering_display_payload->nDisplayPrimariesX[2]) ||
   11366         (hdr_info->sType1.mB.y != mastering_display_payload->nDisplayPrimariesY[2]);
   11367 
   11368     internal_disp_changed_flag |= (hdr_info->sType1.mW.x != mastering_display_payload->nWhitePointX) ||
   11369         (hdr_info->sType1.mW.y != mastering_display_payload->nWhitePointY);
   11370 
   11371     /* Maximum Display Luminance from the bitstream is in 0.0001 cd/m2 while the HDRStaticInfo extension
   11372        requires it in cd/m2, so dividing by 10000 and rounding the value after division
   11373     */
   11374     uint16_t max_display_luminance_cd_m2 =
   11375         static_cast<int>((mastering_display_payload->nMaxDisplayMasteringLuminance / LUMINANCE_DIV_FACTOR) + 0.5);
   11376     internal_disp_changed_flag |= (hdr_info->sType1.mMaxDisplayLuminance != max_display_luminance_cd_m2) ||
   11377         (hdr_info->sType1.mMinDisplayLuminance != mastering_display_payload->nMinDisplayMasteringLuminance);
   11378 
   11379     if (internal_disp_changed_flag) {
   11380         hdr_info->sType1.mR.x = mastering_display_payload->nDisplayPrimariesX[0];
   11381         hdr_info->sType1.mR.y = mastering_display_payload->nDisplayPrimariesY[0];
   11382         hdr_info->sType1.mG.x = mastering_display_payload->nDisplayPrimariesX[1];
   11383         hdr_info->sType1.mG.y = mastering_display_payload->nDisplayPrimariesY[1];
   11384         hdr_info->sType1.mB.x = mastering_display_payload->nDisplayPrimariesX[2];
   11385         hdr_info->sType1.mB.y = mastering_display_payload->nDisplayPrimariesY[2];
   11386         hdr_info->sType1.mW.x = mastering_display_payload->nWhitePointX;
   11387         hdr_info->sType1.mW.y = mastering_display_payload->nWhitePointY;
   11388 
   11389         hdr_info->sType1.mMaxDisplayLuminance = max_display_luminance_cd_m2;
   11390         hdr_info->sType1.mMinDisplayLuminance = mastering_display_payload->nMinDisplayMasteringLuminance;
   11391     }
   11392 
   11393     return internal_disp_changed_flag;
   11394 }
   11395 
   11396 void omx_vdec::set_colormetadata_in_handle(ColorMetaData *color_mdata, unsigned int buf_index)
   11397 {
   11398     private_handle_t *private_handle = NULL;
   11399     if (buf_index < drv_ctx.op_buf.actualcount &&
   11400         buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   11401         native_buffer[buf_index].privatehandle) {
   11402         private_handle = native_buffer[buf_index].privatehandle;
   11403     }
   11404     if (private_handle) {
   11405         setMetaData(private_handle, COLOR_METADATA, (void*)color_mdata);
   11406     }
   11407 }
   11408 
   11409 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   11410 {
   11411     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_client_extra = NULL;
   11412     OMX_U8 *pBuffer = NULL;
   11413     OMX_U32 num_conceal_MB = 0;
   11414     OMX_TICKS time_stamp = 0;
   11415     OMX_U32 frame_rate = 0;
   11416     unsigned long consumed_len = 0;
   11417     OMX_U32 num_MB_in_frame;
   11418     OMX_U32 recovery_sei_flags = 1;
   11419     int enable = OMX_InterlaceFrameProgressive;
   11420     bool internal_hdr_info_changed_flag = false;
   11421     bool color_event = false;
   11422     ColorMetaData color_mdata;
   11423     memset(&color_mdata, 0x0, sizeof(ColorMetaData));
   11424     bool set_disp_color_aspects_only = false;
   11425     ColorSpace_t color_space = ITU_R_601;
   11426 
   11427     int buf_index = p_buf_hdr - m_out_mem_ptr;
   11428     if (buf_index >= drv_ctx.extradata_info.count) {
   11429         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   11430                 buf_index, drv_ctx.extradata_info.count);
   11431         return;
   11432     }
   11433     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   11434 
   11435     if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) {
   11436         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
   11437         return;
   11438     }
   11439 
   11440     if (!drv_ctx.extradata_info.uaddr) {
   11441         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
   11442         return;
   11443     }
   11444     if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
   11445         DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
   11446         p_extra = NULL;
   11447         return;
   11448     }
   11449     if (!secure_mode) {
   11450         pBuffer = (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[buf_index].buffer_len,
   11451                     PROT_READ|PROT_WRITE, MAP_SHARED, drv_ctx.ptr_outputbuffer[buf_index].pmem_fd, 0);
   11452         if (pBuffer == MAP_FAILED) {
   11453             DEBUG_PRINT_ERROR("handle_extradata output buffer mmap failed - errno: %d", errno);
   11454             return;
   11455         }
   11456         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   11457             ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   11458     } else
   11459         p_extra = m_other_extradata;
   11460 
   11461     AutoUnmap autounmap(pBuffer, drv_ctx.ptr_outputbuffer[buf_index].buffer_len);
   11462     if (m_client_output_extradata_mem_ptr &&
   11463         m_client_out_extradata_info.getSize() >= drv_ctx.extradata_info.buffer_size) {
   11464         p_client_extra = (OMX_OTHER_EXTRADATATYPE *)((m_client_output_extradata_mem_ptr + buf_index)->pBuffer);
   11465     }
   11466 
   11467     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   11468 
   11469     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   11470         p_extra = NULL;
   11471         DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   11472         return;
   11473     }
   11474     m_extradata_info.output_crop_updated = OMX_FALSE;
   11475     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   11476     if (data && p_extra) {
   11477         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   11478                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
   11479             if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
   11480                 DEBUG_PRINT_LOW("Invalid extra data size");
   11481                 break;
   11482             }
   11483 
   11484             if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   11485                 p_extra = NULL;
   11486                 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   11487                 return;
   11488             }
   11489 
   11490             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
   11491             switch ((unsigned long)data->eType) {
   11492                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
   11493                     struct msm_vidc_interlace_payload *payload;
   11494                     OMX_U32 interlace_color_format;
   11495                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
   11496                     if (payload) {
   11497                         enable = OMX_InterlaceFrameProgressive;
   11498                         switch (payload->format) {
   11499                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
   11500                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11501                                 break;
   11502                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
   11503                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   11504                                 enable = OMX_InterlaceInterleaveFrameTopFieldFirst;
   11505                                 break;
   11506                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
   11507                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   11508                                 enable = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   11509                                 break;
   11510                             default:
   11511                                 DEBUG_PRINT_LOW("default case - set to progressive");
   11512                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11513                         }
   11514                         switch (payload->color_format) {
   11515                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12:
   11516                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11517                                break;
   11518                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC:
   11519                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11520                                break;
   11521                            default:
   11522                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11523                                DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame");
   11524                         }
   11525                     }
   11526 
   11527                     if (m_enable_android_native_buffers) {
   11528                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d",
   11529                                          payload->format, interlace_color_format ,enable,
   11530                                         (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
   11531 
   11532                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11533                                PP_PARAM_INTERLACED, (void*)&enable);
   11534 
   11535                         if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   11536                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11537                                LINEAR_FORMAT, (void*)&interlace_color_format);
   11538                         } else if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   11539                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   11540                                LINEAR_FORMAT, NULL);
   11541                         }
   11542                     }
   11543                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   11544                         append_interlace_extradata(p_extra, payload->format);
   11545                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11546                         if (p_client_extra) {
   11547                             append_interlace_extradata(p_client_extra, payload->format);
   11548                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *)
   11549                                 (((OMX_U8 *)p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11550                         }
   11551                     }
   11552                     break;
   11553                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
   11554                     struct msm_vidc_framerate_payload *frame_rate_payload;
   11555                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
   11556                     frame_rate = frame_rate_payload->frame_rate;
   11557                     break;
   11558                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
   11559                     struct msm_vidc_ts_payload *time_stamp_payload;
   11560                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
   11561                     time_stamp = time_stamp_payload->timestamp_lo;
   11562                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   11563                     p_buf_hdr->nTimeStamp = time_stamp;
   11564                     break;
   11565                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
   11566                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   11567                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
   11568                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   11569                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   11570                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   11571                     break;
   11572                 case MSM_VIDC_EXTRADATA_INDEX:
   11573                     int *etype;
   11574                     etype  = (int *)(void *)data->data;
   11575                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
   11576                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   11577                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   11578                         if (aspect_ratio_payload) {
   11579                             ((struct vdec_output_frameinfo *)
   11580                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   11581                             ((struct vdec_output_frameinfo *)
   11582                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   11583                         }
   11584                     } else if (etype && *etype == MSM_VIDC_EXTRADATA_OUTPUT_CROP) {
   11585                         struct msm_vidc_output_crop_payload *output_crop_payload;
   11586                         output_crop_payload = (struct msm_vidc_output_crop_payload *)(++etype);
   11587                         if (output_crop_payload) {
   11588                             m_extradata_info.output_crop_rect.nLeft = output_crop_payload->left;
   11589                             m_extradata_info.output_crop_rect.nTop = output_crop_payload->top;
   11590                             m_extradata_info.output_crop_rect.nWidth = output_crop_payload->left + output_crop_payload->display_width;
   11591                             m_extradata_info.output_crop_rect.nHeight = output_crop_payload->top + output_crop_payload->display_height;
   11592                             m_extradata_info.output_width = output_crop_payload->width;
   11593                             m_extradata_info.output_height = output_crop_payload->height;
   11594                             m_extradata_info.output_crop_updated = OMX_TRUE;
   11595                         }
   11596                     }
   11597                     break;
   11598                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
   11599                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   11600                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
   11601                     recovery_sei_flags = recovery_sei_payload->flags;
   11602                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
   11603                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   11604                         DEBUG_PRINT_HIGH("***************************************************");
   11605                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   11606                         DEBUG_PRINT_HIGH("***************************************************");
   11607                     }
   11608                     break;
   11609                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
   11610                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
   11611                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
   11612                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
   11613                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
   11614                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
   11615                         return;
   11616                     }
   11617                     break;
   11618                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
   11619                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
   11620                 case MSM_VIDC_EXTRADATA_VC1_SEQDISP:
   11621                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
   11622                     color_event = handle_color_space_info((void *)data->data, &color_space, &color_mdata, set_disp_color_aspects_only);
   11623                     break;
   11624                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
   11625                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
   11626                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
   11627                     switch (s3d_frame_packing_payload->fpa_type) {
   11628                         case MSM_VIDC_FRAMEPACK_SIDE_BY_SIDE:
   11629                             if (s3d_frame_packing_payload->content_interprtation_type == 1)
   11630                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_L_R;
   11631                             else if (s3d_frame_packing_payload->content_interprtation_type == 2)
   11632                                 stereo_output_mode = HAL_3D_SIDE_BY_SIDE_R_L;
   11633                             else {
   11634                                 DEBUG_PRINT_ERROR("Unsupported side-by-side framepacking type");
   11635                                 stereo_output_mode = HAL_NO_3D;
   11636                             }
   11637                             break;
   11638                         case MSM_VIDC_FRAMEPACK_TOP_BOTTOM:
   11639                             stereo_output_mode = HAL_3D_TOP_BOTTOM;
   11640                             break;
   11641                         default:
   11642                             DEBUG_PRINT_ERROR("Unsupported framepacking type");
   11643                             stereo_output_mode = HAL_NO_3D;
   11644                     }
   11645                     DEBUG_PRINT_LOW("setMetaData FRAMEPACKING : fpa_type = %u, content_interprtation_type = %u, stereo_output_mode= %d",
   11646                         s3d_frame_packing_payload->fpa_type, s3d_frame_packing_payload->content_interprtation_type, stereo_output_mode);
   11647                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
   11648                         append_framepack_extradata(p_extra, s3d_frame_packing_payload);
   11649                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11650                         if (p_client_extra) {
   11651                             append_framepack_extradata(p_client_extra, s3d_frame_packing_payload);
   11652                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11653                         }
   11654                     }
   11655                     break;
   11656                 case MSM_VIDC_EXTRADATA_FRAME_QP:
   11657                     struct msm_vidc_frame_qp_payload *qp_payload;
   11658                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
   11659                     if (client_extradata & OMX_QP_EXTRADATA) {
   11660                         append_qp_extradata(p_extra, qp_payload);
   11661                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11662                         if (p_client_extra) {
   11663                             append_qp_extradata(p_client_extra, qp_payload);
   11664                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11665                         }
   11666                     }
   11667                     break;
   11668                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
   11669                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
   11670                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
   11671                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
   11672                         append_bitsinfo_extradata(p_extra, bits_info_payload);
   11673                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11674                         if (p_client_extra) {
   11675                             append_bitsinfo_extradata(p_client_extra, bits_info_payload);
   11676                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11677                         }
   11678                     }
   11679                     break;
   11680                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
   11681                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
   11682                         append_user_extradata(p_extra, data);
   11683                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11684                         if (p_client_extra) {
   11685                             append_user_extradata(p_client_extra, data);
   11686                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11687                         }
   11688                     }
   11689                     break;
   11690                 case MSM_VIDC_EXTRADATA_VQZIP_SEI:
   11691                     struct msm_vidc_vqzip_sei_payload *vqzip_payload;
   11692                     vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data;
   11693                     if (client_extradata & OMX_VQZIPSEI_EXTRADATA) {
   11694                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11695                         append_vqzip_extradata(p_extra, vqzip_payload);
   11696                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11697                         if (p_client_extra) {
   11698                             append_vqzip_extradata(p_client_extra, vqzip_payload);
   11699                             p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11700                         }
   11701                     }
   11702                     break;
   11703                 case MSM_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI:
   11704 
   11705                     internal_hdr_info_changed_flag |= handle_content_light_level_info((void*)data->data,
   11706                                                                                       &(color_mdata.contentLightLevel));
   11707                     break;
   11708                 case MSM_VIDC_EXTRADATA_MASTERING_DISPLAY_COLOUR_SEI:
   11709                     internal_hdr_info_changed_flag |= handle_mastering_display_color_info((void*)data->data,
   11710                                                                                           &(color_mdata.masteringDisplayInfo));
   11711                     break;
   11712                 default:
   11713                     DEBUG_PRINT_LOW("Unrecognized extradata");
   11714                     goto unrecognized_extradata;
   11715             }
   11716             consumed_len += data->nSize;
   11717             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   11718         }
   11719         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   11720             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11721             append_frame_info_extradata(p_extra,
   11722                     num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   11723                     time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   11724                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   11725             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11726             if (p_client_extra) {
   11727                 append_frame_info_extradata(p_client_extra,
   11728                         num_conceal_MB, recovery_sei_flags, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   11729                         time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   11730                             p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   11731                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11732             }
   11733         }
   11734         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
   11735             append_frame_dimension_extradata(p_extra);
   11736             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + ALIGN(p_extra->nSize, 4));
   11737             if (p_client_extra) {
   11738                 append_frame_dimension_extradata(p_client_extra);
   11739                 p_client_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_client_extra) + ALIGN(p_client_extra->nSize, 4));
   11740             }
   11741         }
   11742 
   11743         if(internal_hdr_info_changed_flag) {
   11744             print_debug_hdr_color_info(&(m_internal_hdr_info.sInfo), "Internal");
   11745             print_debug_hdr_color_info(&(m_client_hdr_info.sInfo), "Client");
   11746             memcpy(&m_color_mdata, &color_mdata, sizeof(ColorMetaData));
   11747             auto_lock lock(m_hdr_info_client_lock);
   11748             m_change_client_hdr_info = true;
   11749             if(!color_event) {
   11750                 DEBUG_PRINT_HIGH("Initiating PORT Reconfig due to HDR Info Change");
   11751                 post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   11752                            OMX_QTIIndexConfigDescribeHDRColorInfo,
   11753                            OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   11754             }
   11755         }
   11756 
   11757         if (m_enable_android_native_buffers) {
   11758             if (set_disp_color_aspects_only) {
   11759                 print_debug_hdr_color_info_mdata(&m_color_mdata);
   11760                 set_colormetadata_in_handle(&m_color_mdata, buf_index);
   11761             } else {
   11762                 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);
   11763                 set_colorspace_in_handle(color_space, buf_index);
   11764             }
   11765         }
   11766 
   11767     }
   11768 unrecognized_extradata:
   11769     if (client_extradata && p_extra) {
   11770         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   11771         append_terminator_extradata(p_extra);
   11772         if (p_client_extra) {
   11773             append_terminator_extradata(p_client_extra);
   11774         }
   11775     }
   11776     if (secure_mode && p_extradata && m_other_extradata) {
   11777         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
   11778         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
   11779         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
   11780         ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
   11781         ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
   11782         ptr_extradatabuff->metadata_info.fd = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   11783         ptr_extradatabuff->metadata_info.offset = buf_index * drv_ctx.extradata_info.buffer_size;
   11784         ptr_extradatabuff->metadata_info.buffer_size = drv_ctx.extradata_info.size;
   11785     }
   11786     return;
   11787 }
   11788 
   11789 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U64 requested_extradata,
   11790         bool is_internal, bool enable)
   11791 {
   11792     OMX_ERRORTYPE ret = OMX_ErrorNone;
   11793     struct v4l2_control control;
   11794     if (m_state != OMX_StateLoaded) {
   11795         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   11796         return OMX_ErrorIncorrectStateOperation;
   11797     }
   11798     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
   11799             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
   11800 
   11801     if (!is_internal) {
   11802         if (enable)
   11803             client_extradata |= requested_extradata;
   11804         else
   11805             client_extradata = client_extradata & ~requested_extradata;
   11806     }
   11807 
   11808     if (enable) {
   11809         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   11810             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11811             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   11812             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11813                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   11814                         " Quality of interlaced clips might be impacted.");
   11815             }
   11816         }
   11817         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   11818             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11819             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   11820             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11821                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
   11822             }
   11823             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11824             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   11825             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11826                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
   11827             }
   11828             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11829             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   11830             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11831                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
   11832             }
   11833             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11834             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   11835             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11836                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11837             }
   11838             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11839             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
   11840             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11841                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11842             }
   11843             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   11844                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11845                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   11846                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11847                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   11848                 }
   11849             }
   11850         }
   11851         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   11852             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11853             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   11854             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11855                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
   11856             }
   11857         }
   11858         if (!secure_mode && (requested_extradata & OMX_FRAMEPACK_EXTRADATA)) {
   11859             if (output_capability == V4L2_PIX_FMT_H264) {
   11860                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
   11861                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11862                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
   11863                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11864                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
   11865                 }
   11866             } else {
   11867                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
   11868             }
   11869         }
   11870         if (requested_extradata & OMX_QP_EXTRADATA) {
   11871             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11872             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   11873             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11874                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   11875             }
   11876         }
   11877         if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
   11878             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11879             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
   11880             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11881                 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
   11882             }
   11883         }
   11884         if (!secure_mode && (requested_extradata & OMX_EXTNUSER_EXTRADATA)) {
   11885             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11886             control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
   11887             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11888                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
   11889             }
   11890         }
   11891         if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) {
   11892             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11893             control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI;
   11894             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11895                 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata");
   11896             }
   11897             client_extradata |= OMX_VQZIPSEI_EXTRADATA;
   11898 
   11899             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11900             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   11901             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11902                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   11903             }
   11904             client_extradata |= OMX_QP_EXTRADATA;
   11905         }
   11906         if (requested_extradata & OMX_OUTPUTCROP_EXTRADATA) {
   11907             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11908             control.value = V4L2_MPEG_VIDC_EXTRADATA_OUTPUT_CROP;
   11909             DEBUG_PRINT_LOW("Enable output crop extra data");
   11910             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11911                 DEBUG_PRINT_HIGH("Failed to set output crop extradata");
   11912             }
   11913         }
   11914         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
   11915             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11916             switch(output_capability) {
   11917                 case V4L2_PIX_FMT_H264:
   11918                 case V4L2_PIX_FMT_HEVC:
   11919                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
   11920                     break;
   11921                 case CODEC_TYPE_MPEG2:
   11922                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   11923                     break;
   11924                 case V4L2_PIX_FMT_VP8:
   11925                 case V4L2_PIX_FMT_VP9:
   11926                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
   11927                     break;
   11928                 case V4L2_PIX_FMT_VC1_ANNEX_G:
   11929                 case V4L2_PIX_FMT_VC1_ANNEX_L:
   11930                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP;
   11931                     break;
   11932                 default:
   11933                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
   11934                     return ret;
   11935             }
   11936 
   11937             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11938                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
   11939             }
   11940         }
   11941         if (requested_extradata & OMX_HDR_COLOR_INFO_EXTRADATA) {
   11942             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   11943             if (output_capability == V4L2_PIX_FMT_H264 ||
   11944                 output_capability == V4L2_PIX_FMT_HEVC) {
   11945                 control.value = V4L2_MPEG_VIDC_EXTRADATA_DISPLAY_COLOUR_SEI;
   11946                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11947                     DEBUG_PRINT_HIGH("Failed to set Display Colour SEI extradata");
   11948                 }
   11949                 control.value = V4L2_MPEG_VIDC_EXTRADATA_CONTENT_LIGHT_LEVEL_SEI;
   11950                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11951                     DEBUG_PRINT_HIGH("Failed to set Content Light Level SEI extradata");
   11952                 }
   11953             }
   11954         }
   11955     }
   11956     ret = get_buffer_req(&drv_ctx.op_buf);
   11957     return ret;
   11958 }
   11959 
   11960 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11961 {
   11962     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   11963     OMX_U8 *data_ptr = extra->data, data = 0;
   11964     while (byte_count < extra->nDataSize) {
   11965         data = *data_ptr;
   11966         while (data) {
   11967             num_MB += (data&0x01);
   11968             data >>= 1;
   11969         }
   11970         data_ptr++;
   11971         byte_count++;
   11972     }
   11973     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   11974             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   11975     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   11976 }
   11977 
   11978 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11979 {
   11980     if (!m_debug_extradata || !extra)
   11981         return;
   11982 
   11983 
   11984     DEBUG_PRINT_HIGH(
   11985             "============== Extra Data ==============\n"
   11986             "           Size: %u\n"
   11987             "        Version: %u\n"
   11988             "      PortIndex: %u\n"
   11989             "           Type: %x\n"
   11990             "       DataSize: %u",
   11991             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
   11992             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
   11993 
   11994     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   11995         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   11996         DEBUG_PRINT_HIGH(
   11997                 "------ Interlace Format ------\n"
   11998                 "                Size: %u\n"
   11999                 "             Version: %u\n"
   12000                 "           PortIndex: %u\n"
   12001                 " Is Interlace Format: %d\n"
   12002                 "   Interlace Formats: %u\n"
   12003                 "=========== End of Interlace ===========",
   12004                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
   12005                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
   12006     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   12007         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   12008 
   12009         DEBUG_PRINT_HIGH(
   12010                 "-------- Frame Format --------\n"
   12011                 "             Picture Type: %d\n"
   12012                 "           Interlace Type: %d\n"
   12013                 " Pan Scan Total Frame Num: %u\n"
   12014                 "   Concealed Macro Blocks: %u\n"
   12015                 "        Recovery SEI Flag: %u\n"
   12016                 "               frame rate: %u\n"
   12017                 "               Time Stamp: %llu\n"
   12018                 "           Aspect Ratio X: %u\n"
   12019                 "           Aspect Ratio Y: %u",
   12020                 fminfo->ePicType,
   12021                 fminfo->interlaceType,
   12022                 (unsigned int)fminfo->panScan.numWindows,
   12023                 (unsigned int)fminfo->nConcealedMacroblocks,
   12024                 (unsigned int)fminfo->nRecoverySeiFlag,
   12025                 (unsigned int)fminfo->nFrameRate,
   12026                 fminfo->nTimeStamp,
   12027                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
   12028                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
   12029 
   12030         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   12031             DEBUG_PRINT_HIGH(
   12032                     "------------------------------"
   12033                     "     Pan Scan Frame Num: %u\n"
   12034                     "            Rectangle x: %d\n"
   12035                     "            Rectangle y: %d\n"
   12036                     "           Rectangle dx: %d\n"
   12037                     "           Rectangle dy: %d",
   12038                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
   12039                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
   12040         }
   12041 
   12042         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   12043     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
   12044         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   12045         DEBUG_PRINT_HIGH(
   12046                 "------------------ Framepack Format ----------\n"
   12047                 "                           id: %u \n"
   12048                 "                  cancel_flag: %u \n"
   12049                 "                         type: %u \n"
   12050                 " quincunx_sampling_flagFormat: %u \n"
   12051                 "  content_interpretation_type: %u \n"
   12052                 "        spatial_flipping_flag: %u \n"
   12053                 "          frame0_flipped_flag: %u \n"
   12054                 "             field_views_flag: %u \n"
   12055                 " current_frame_is_frame0_flag: %u \n"
   12056                 "   frame0_self_contained_flag: %u \n"
   12057                 "   frame1_self_contained_flag: %u \n"
   12058                 "       frame0_grid_position_x: %u \n"
   12059                 "       frame0_grid_position_y: %u \n"
   12060                 "       frame1_grid_position_x: %u \n"
   12061                 "       frame1_grid_position_y: %u \n"
   12062                 "                reserved_byte: %u \n"
   12063                 "            repetition_period: %u \n"
   12064                 "               extension_flag: %u \n"
   12065                 "================== End of Framepack ===========",
   12066                 (unsigned int)framepack->id,
   12067                 (unsigned int)framepack->cancel_flag,
   12068                 (unsigned int)framepack->type,
   12069                 (unsigned int)framepack->quincunx_sampling_flag,
   12070                 (unsigned int)framepack->content_interpretation_type,
   12071                 (unsigned int)framepack->spatial_flipping_flag,
   12072                 (unsigned int)framepack->frame0_flipped_flag,
   12073                 (unsigned int)framepack->field_views_flag,
   12074                 (unsigned int)framepack->current_frame_is_frame0_flag,
   12075                 (unsigned int)framepack->frame0_self_contained_flag,
   12076                 (unsigned int)framepack->frame1_self_contained_flag,
   12077                 (unsigned int)framepack->frame0_grid_position_x,
   12078                 (unsigned int)framepack->frame0_grid_position_y,
   12079                 (unsigned int)framepack->frame1_grid_position_x,
   12080                 (unsigned int)framepack->frame1_grid_position_y,
   12081                 (unsigned int)framepack->reserved_byte,
   12082                 (unsigned int)framepack->repetition_period,
   12083                 (unsigned int)framepack->extension_flag);
   12084     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
   12085         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   12086         DEBUG_PRINT_HIGH(
   12087                 "---- QP (Frame quantization parameter) ----\n"
   12088                 "    Frame QP: %u \n"
   12089                 "================ End of QP ================\n",
   12090                 (unsigned int)qp->nQP);
   12091     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
   12092         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
   12093         DEBUG_PRINT_HIGH(
   12094                 "--------- Input bits information --------\n"
   12095                 "    Header bits: %u \n"
   12096                 "     Frame bits: %u \n"
   12097                 "===== End of Input bits information =====\n",
   12098                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
   12099     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
   12100         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
   12101         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
   12102         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
   12103         OMX_U32 i = 0;
   12104         DEBUG_PRINT_HIGH(
   12105                 "--------------  Userdata  -------------\n"
   12106                 "    Stream userdata type: %u\n"
   12107                 "          userdata size: %u\n"
   12108                 "    STREAM_USERDATA:",
   12109                 (unsigned int)userdata->type, (unsigned int)userdata_size);
   12110                 for (i = 0; i < userdata_size; i+=4) {
   12111                     DEBUG_PRINT_HIGH("        %x %x %x %x",
   12112                         data_ptr[i], data_ptr[i+1],
   12113                         data_ptr[i+2], data_ptr[i+3]);
   12114                 }
   12115         DEBUG_PRINT_HIGH(
   12116                 "=========== End of Userdata ===========");
   12117     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
   12118         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   12119         DEBUG_PRINT_HIGH(
   12120                 "--------------  VQZip  -------------\n"
   12121                 "    Size: %u\n",
   12122                 (unsigned int)vq->nSize);
   12123         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
   12124     } else if (extra->eType == OMX_ExtraDataNone) {
   12125         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   12126     } else {
   12127         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   12128     }
   12129 }
   12130 
   12131 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12132         OMX_U32 interlaced_format_type)
   12133 {
   12134     OMX_STREAMINTERLACEFORMAT *interlace_format;
   12135 
   12136     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   12137         return;
   12138     }
   12139     if (!extra) {
   12140        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
   12141        return;
   12142     }
   12143     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   12144     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12145     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12146     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   12147     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   12148     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   12149     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   12150     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   12151     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12152 
   12153     if (interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) {
   12154         interlace_format->bInterlaceFormat = OMX_FALSE;
   12155         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   12156         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   12157     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) {
   12158         interlace_format->bInterlaceFormat = OMX_TRUE;
   12159         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   12160         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   12161     } else if (interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) {
   12162         interlace_format->bInterlaceFormat = OMX_TRUE;
   12163         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   12164         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   12165     } else {
   12166         //default case - set to progressive
   12167         interlace_format->bInterlaceFormat = OMX_FALSE;
   12168         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   12169         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   12170     }
   12171     print_debug_extradata(extra);
   12172 }
   12173 
   12174 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12175 {
   12176     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
   12177     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
   12178         return;
   12179     }
   12180     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
   12181     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12182     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12183     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
   12184     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
   12185     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
   12186     frame_dimension->nDecWidth = rectangle.nLeft;
   12187     frame_dimension->nDecHeight = rectangle.nTop;
   12188     frame_dimension->nActualWidth = rectangle.nWidth;
   12189     frame_dimension->nActualHeight = rectangle.nHeight;
   12190 }
   12191 
   12192 void omx_vdec::fill_aspect_ratio_info(
   12193         struct vdec_aspectratioinfo *aspect_ratio_info,
   12194         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   12195 {
   12196     m_extradata = frame_info;
   12197     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   12198     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   12199     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
   12200             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
   12201 }
   12202 
   12203 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12204         OMX_U32 num_conceal_mb, OMX_U32 recovery_sei_flag, OMX_U32 picture_type, OMX_U32 frame_rate,
   12205         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
   12206         struct vdec_aspectratioinfo *aspect_ratio_info)
   12207 {
   12208     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   12209     struct msm_vidc_panscan_window *panscan_window;
   12210     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   12211         return;
   12212     }
   12213     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   12214     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12215     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12216     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   12217     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   12218     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   12219     switch (picture_type) {
   12220         case PICTURE_TYPE_I:
   12221             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   12222             break;
   12223         case PICTURE_TYPE_P:
   12224             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   12225             break;
   12226         case PICTURE_TYPE_B:
   12227             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   12228             break;
   12229         default:
   12230             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   12231     }
   12232     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   12233         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   12234     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   12235         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   12236     else
   12237         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   12238     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   12239     frame_info->nConcealedMacroblocks = num_conceal_mb;
   12240     frame_info->nRecoverySeiFlag = recovery_sei_flag;
   12241     frame_info->nFrameRate = frame_rate;
   12242     frame_info->nTimeStamp = time_stamp;
   12243     frame_info->panScan.numWindows = 0;
   12244     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   12245         if (m_disp_hor_size && m_disp_vert_size) {
   12246             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   12247             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   12248         } else {
   12249             frame_info->displayAspectRatio.displayHorizontalSize = 0;
   12250             frame_info->displayAspectRatio.displayVerticalSize = 0;
   12251         }
   12252     }
   12253 
   12254     if (panscan_payload) {
   12255         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   12256         panscan_window = &panscan_payload->wnd[0];
   12257         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   12258             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   12259             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   12260             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   12261             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   12262             panscan_window++;
   12263         }
   12264     }
   12265     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   12266     print_debug_extradata(extra);
   12267 }
   12268 
   12269 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12270 {
   12271     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   12272     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   12273     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12274     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12275     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   12276     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   12277     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
   12278     *portDefn = m_port_def;
   12279     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
   12280             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
   12281             (unsigned int)portDefn->format.video.nFrameWidth,
   12282             (unsigned int)portDefn->format.video.nStride,
   12283             (unsigned int)portDefn->format.video.nSliceHeight);
   12284 }
   12285 
   12286 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12287         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
   12288 {
   12289     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
   12290     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
   12291         DEBUG_PRINT_ERROR("frame packing size mismatch");
   12292         return;
   12293     }
   12294     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
   12295     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12296     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12297     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
   12298     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   12299     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   12300     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   12301     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
   12302     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12303     memcpy(&framepack->id, s3d_frame_packing_payload,
   12304         sizeof(struct msm_vidc_s3d_frame_packing_payload));
   12305     memcpy(&m_frame_pack_arrangement, framepack,
   12306         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   12307     print_debug_extradata(extra);
   12308 }
   12309 
   12310 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12311             struct msm_vidc_frame_qp_payload *qp_payload)
   12312 {
   12313     OMX_QCOM_EXTRADATA_QP * qp = NULL;
   12314     if (!qp_payload) {
   12315         DEBUG_PRINT_ERROR("QP payload is NULL");
   12316         return;
   12317     }
   12318     extra->nSize = OMX_QP_EXTRADATA_SIZE;
   12319     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12320     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12321     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
   12322     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
   12323     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   12324     qp->nQP = qp_payload->frame_qp;
   12325     print_debug_extradata(extra);
   12326 }
   12327 
   12328 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12329             struct msm_vidc_frame_bits_info_payload *bits_payload)
   12330 {
   12331     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
   12332     if (!bits_payload) {
   12333         DEBUG_PRINT_ERROR("bits info payload is NULL");
   12334         return;
   12335     }
   12336     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
   12337     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12338     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12339     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
   12340     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
   12341     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
   12342     bits->frame_bits = bits_payload->frame_bits;
   12343     bits->header_bits = bits_payload->header_bits;
   12344     print_debug_extradata(extra);
   12345 }
   12346 
   12347 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12348             OMX_OTHER_EXTRADATATYPE *p_user)
   12349 {
   12350     int userdata_size = 0;
   12351     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
   12352     userdata_payload =
   12353         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
   12354     userdata_size = p_user->nDataSize;
   12355     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
   12356     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12357     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12358     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
   12359     extra->nDataSize = userdata_size;
   12360     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
   12361         memcpy(extra->data, p_user->data, extra->nDataSize);
   12362     print_debug_extradata(extra);
   12363 }
   12364 
   12365 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   12366 {
   12367     if (!client_extradata) {
   12368         return;
   12369     }
   12370     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   12371     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12372     extra->eType = OMX_ExtraDataNone;
   12373     extra->nDataSize = 0;
   12374     extra->data[0] = 0;
   12375 
   12376     print_debug_extradata(extra);
   12377 }
   12378 
   12379 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   12380         struct msm_vidc_vqzip_sei_payload *vqzip_payload)
   12381 {
   12382     OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL;
   12383 
   12384     extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size;
   12385     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   12386     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12387     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI;
   12388     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size;
   12389 
   12390     vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   12391     vq->nSize = vqzip_payload->size;
   12392     memcpy(vq->data, vqzip_payload->data, vqzip_payload->size);
   12393 
   12394     print_debug_extradata(extra);
   12395 }
   12396 
   12397 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   12398 {
   12399     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12400     if (index >= drv_ctx.ip_buf.actualcount) {
   12401         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
   12402         return OMX_ErrorInsufficientResources;
   12403     }
   12404     if (m_desc_buffer_ptr == NULL) {
   12405         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   12406                     calloc( (sizeof(desc_buffer_hdr)),
   12407                             drv_ctx.ip_buf.actualcount);
   12408         if (m_desc_buffer_ptr == NULL) {
   12409             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
   12410             return OMX_ErrorInsufficientResources;
   12411         }
   12412     }
   12413 
   12414     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   12415     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   12416         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
   12417         return OMX_ErrorInsufficientResources;
   12418     }
   12419 
   12420     return eRet;
   12421 }
   12422 
   12423 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   12424 {
   12425     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
   12426     if (m_demux_entries < 8192) {
   12427         m_demux_offsets[m_demux_entries++] = address_offset;
   12428     }
   12429     return;
   12430 }
   12431 
   12432 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   12433 {
   12434     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   12435     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   12436     OMX_U32 index = 0;
   12437 
   12438     m_demux_entries = 0;
   12439 
   12440     while (index < bytes_to_parse) {
   12441         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   12442                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   12443                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   12444                  (buf[index+2] == 0x01)) ) {
   12445             //Found start code, insert address offset
   12446             insert_demux_addr_offset(index);
   12447             if (buf[index+2] == 0x01) // 3 byte start code
   12448                 index += 3;
   12449             else                      //4 byte start code
   12450                 index += 4;
   12451         } else
   12452             index++;
   12453     }
   12454     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
   12455     return;
   12456 }
   12457 
   12458 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   12459 {
   12460     //fix this, handle 3 byte start code, vc1 terminator entry
   12461     OMX_U8 *p_demux_data = NULL;
   12462     OMX_U32 desc_data = 0;
   12463     OMX_U32 start_addr = 0;
   12464     OMX_U32 nal_size = 0;
   12465     OMX_U32 suffix_byte = 0;
   12466     OMX_U32 demux_index = 0;
   12467     OMX_U32 buffer_index = 0;
   12468 
   12469     if (m_desc_buffer_ptr == NULL) {
   12470         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   12471         return OMX_ErrorBadParameter;
   12472     }
   12473 
   12474     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   12475     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   12476         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
   12477         return OMX_ErrorBadParameter;
   12478     }
   12479 
   12480     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   12481 
   12482     if ( ((OMX_U8*)p_demux_data == NULL) ||
   12483             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   12484         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   12485         return OMX_ErrorBadParameter;
   12486     } else {
   12487         for (; demux_index < m_demux_entries; demux_index++) {
   12488             desc_data = 0;
   12489             start_addr = m_demux_offsets[demux_index];
   12490             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   12491                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   12492             } else {
   12493                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   12494             }
   12495             if (demux_index < (m_demux_entries - 1)) {
   12496                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   12497             } else {
   12498                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   12499             }
   12500             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
   12501                     (unsigned int)start_addr,
   12502                     (unsigned int)suffix_byte,
   12503                     (unsigned int)nal_size,
   12504                     (unsigned int)demux_index);
   12505             desc_data = (start_addr >> 3) << 1;
   12506             desc_data |= (start_addr & 7) << 21;
   12507             desc_data |= suffix_byte << 24;
   12508 
   12509             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   12510             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   12511             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   12512             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   12513 
   12514             p_demux_data += 16;
   12515         }
   12516         if (codec_type_parse == CODEC_TYPE_VC1) {
   12517             DEBUG_PRINT_LOW("VC1 terminator entry");
   12518             desc_data = 0;
   12519             desc_data = 0x82 << 24;
   12520             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   12521             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   12522             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   12523             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   12524             p_demux_data += 16;
   12525             m_demux_entries++;
   12526         }
   12527         //Add zero word to indicate end of descriptors
   12528         memset(p_demux_data, 0, sizeof(OMX_U32));
   12529 
   12530         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   12531         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
   12532     }
   12533     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   12534     m_demux_entries = 0;
   12535     DEBUG_PRINT_LOW("Demux table complete!");
   12536     return OMX_ErrorNone;
   12537 }
   12538 
   12539 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level)
   12540 {
   12541     struct v4l2_control control;
   12542     char property_value[PROPERTY_VALUE_MAX] = {0};
   12543 
   12544     property_get("vendor.vidc.debug.turbo", property_value, "0");
   12545     memset(&control, 0, sizeof(v4l2_control));
   12546     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   12547     switch (perf_level) {
   12548     case VIDC_NOMINAL:
   12549         if (atoi(property_value))
   12550             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   12551         else
   12552             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   12553         break;
   12554     case VIDC_TURBO:
   12555         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   12556         break;
   12557      default:
   12558         DEBUG_PRINT_ERROR("Requested PERF level not supported");
   12559         break;
   12560     }
   12561     if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig)
   12562         return;
   12563 
   12564     DEBUG_PRINT_HIGH("changing performance level to %d", control.value);
   12565     if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   12566         current_perf_level = control.value;
   12567     } else {
   12568         DEBUG_PRINT_ERROR("Failed to set PERF level");
   12569     }
   12570 }
   12571 
   12572 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   12573 {
   12574     enabled = false;
   12575     omx = NULL;
   12576     init_members();
   12577     ColorFormat = OMX_COLOR_FormatMax;
   12578     dest_format = YCbCr420P;
   12579     m_c2d_width = 0;
   12580     m_c2d_height = 0;
   12581 }
   12582 
   12583 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   12584 {
   12585     omx = reinterpret_cast<omx_vdec*>(client);
   12586 }
   12587 
   12588 void omx_vdec::allocate_color_convert_buf::init_members()
   12589 {
   12590     allocated_count = 0;
   12591     buffer_size_req = 0;
   12592     buffer_alignment_req = 0;
   12593     m_c2d_width = m_c2d_height = 0;
   12594     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   12595     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   12596     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   12597     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   12598 #ifdef USE_ION
   12599     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   12600 #endif
   12601     for (int i = 0; i < MAX_COUNT; i++)
   12602         pmem_fd[i] = -1;
   12603 }
   12604 
   12605 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   12606 {
   12607     c2d.destroy();
   12608 }
   12609 
   12610 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   12611 {
   12612     bool status = true;
   12613     unsigned int src_size = 0, destination_size = 0;
   12614     unsigned int height, width;
   12615     struct v4l2_format fmt;
   12616     OMX_COLOR_FORMATTYPE drv_color_format;
   12617 
   12618     if (!omx) {
   12619         DEBUG_PRINT_ERROR("Invalid client in color convert");
   12620         return false;
   12621     }
   12622     if (!enabled) {
   12623         DEBUG_PRINT_HIGH("No color conversion required");
   12624         return status;
   12625     }
   12626     pthread_mutex_lock(&omx->c_lock);
   12627 
   12628     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   12629     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   12630     fmt.fmt.pix_mp.pixelformat = omx->capture_capability;
   12631     ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   12632     width = fmt.fmt.pix_mp.width;
   12633     height =  fmt.fmt.pix_mp.height;
   12634 
   12635     bool resolution_upgrade = (height > m_c2d_height ||
   12636             width > m_c2d_width);
   12637     if (resolution_upgrade) {
   12638         // resolution upgraded ? ensure we are yet to allocate;
   12639         // failing which, c2d buffers will never be reallocated and bad things will happen
   12640         if (allocated_count > 0) {
   12641             DEBUG_PRINT_ERROR("Cannot change C2D buffer requirements with %d active allocations",
   12642                     allocated_count);
   12643             status = false;
   12644             goto fail_update_buf_req;
   12645         }
   12646     }
   12647 
   12648     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   12649             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   12650         DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
   12651         status = false;
   12652         goto fail_update_buf_req;
   12653     }
   12654     c2d.close();
   12655     status = c2d.open(height,
   12656             width,
   12657             NV12_128m,dest_format);
   12658     if (status) {
   12659         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   12660         if (status)
   12661             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   12662     }
   12663     if (status) {
   12664         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   12665                 !destination_size) {
   12666             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
   12667                     "driver size %u destination size %d",
   12668                     src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
   12669                     destination_size);
   12670             status = false;
   12671             c2d.close();
   12672             buffer_size_req = 0;
   12673             // TODO: make this fatal. Driver is not supposed to quote size
   12674             //  smaller than what C2D needs !!
   12675         } else {
   12676             buffer_size_req = destination_size;
   12677             m_c2d_height = height;
   12678             m_c2d_width = width;
   12679         }
   12680     }
   12681 fail_update_buf_req:
   12682     pthread_mutex_unlock(&omx->c_lock);
   12683     return status;
   12684 }
   12685 
   12686 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   12687         OMX_COLOR_FORMATTYPE dest_color_format)
   12688 {
   12689     bool status = true, drv_colorformat_c2d_enable = false;
   12690     bool dest_color_format_c2d_enable = false;
   12691     OMX_COLOR_FORMATTYPE drv_color_format = OMX_COLOR_FormatUnused;
   12692     if (!omx) {
   12693         DEBUG_PRINT_ERROR("Invalid client in color convert");
   12694         return false;
   12695     }
   12696     pthread_mutex_lock(&omx->c_lock);
   12697     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   12698         if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   12699             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12700                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   12701         else
   12702             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12703                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   12704      else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   12705          drv_color_format = (OMX_COLOR_FORMATTYPE)
   12706                   QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   12707      } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC) {
   12708             drv_color_format = (OMX_COLOR_FORMATTYPE)
   12709                     QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
   12710      } else {
   12711         DEBUG_PRINT_ERROR("Incorrect color format");
   12712         status = false;
   12713     }
   12714     drv_colorformat_c2d_enable = (drv_color_format != dest_color_format) &&
   12715         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12716                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) &&
   12717         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12718                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
   12719         (drv_color_format != (OMX_COLOR_FORMATTYPE)
   12720                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
   12721 
   12722     dest_color_format_c2d_enable = (dest_color_format != (OMX_COLOR_FORMATTYPE)
   12723             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) &&
   12724             (dest_color_format != (OMX_COLOR_FORMATTYPE)
   12725                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed);
   12726 
   12727     if (status && drv_colorformat_c2d_enable && dest_color_format_c2d_enable) {
   12728         DEBUG_PRINT_LOW("Enabling C2D");
   12729         if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
   12730            (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
   12731             DEBUG_PRINT_ERROR("Unsupported color format for c2d");
   12732             status = false;
   12733         } else {
   12734             ColorFormat = dest_color_format;
   12735             dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
   12736                     YCbCr420P : YCbCr420SP;
   12737             if (enabled)
   12738                 c2d.destroy();
   12739             enabled = false;
   12740             if (!c2d.init()) {
   12741                 DEBUG_PRINT_ERROR("open failed for c2d");
   12742                 status = false;
   12743             } else
   12744                 enabled = true;
   12745         }
   12746     } else {
   12747         if (enabled)
   12748             c2d.destroy();
   12749         enabled = false;
   12750     }
   12751     pthread_mutex_unlock(&omx->c_lock);
   12752     return status;
   12753 }
   12754 
   12755 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   12756 {
   12757     if (!omx) {
   12758         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12759         return NULL;
   12760     }
   12761     if (!enabled)
   12762         return omx->m_out_mem_ptr;
   12763     return m_out_mem_ptr_client;
   12764 }
   12765 
   12766     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   12767 (OMX_BUFFERHEADERTYPE *bufadd)
   12768 {
   12769     if (!omx) {
   12770         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12771         return NULL;
   12772     }
   12773     if (!enabled)
   12774         return bufadd;
   12775 
   12776     unsigned index = 0;
   12777     index = bufadd - omx->m_out_mem_ptr;
   12778     if (index < omx->drv_ctx.op_buf.actualcount) {
   12779         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   12780         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   12781         bool status;
   12782         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   12783             pthread_mutex_lock(&omx->c_lock);
   12784             cache_clean_buffer(index);
   12785             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   12786                     omx->drv_ctx.op_buf_map_info[index].base_address, bufadd->pBuffer, pmem_fd[index],
   12787                     pmem_baseaddress[index], pmem_baseaddress[index]);
   12788             if (!status) {
   12789                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
   12790                 m_out_mem_ptr_client[index].nFilledLen = 0;
   12791                 pthread_mutex_unlock(&omx->c_lock);
   12792                 return &m_out_mem_ptr_client[index];
   12793             } else {
   12794                 unsigned int filledLen = 0;
   12795                 c2d.get_output_filled_length(filledLen);
   12796                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
   12797                 cache_clean_invalidate_buffer(index);
   12798             }
   12799             pthread_mutex_unlock(&omx->c_lock);
   12800         } else
   12801             m_out_mem_ptr_client[index].nFilledLen = 0;
   12802         return &m_out_mem_ptr_client[index];
   12803     }
   12804     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
   12805     return NULL;
   12806 }
   12807 
   12808     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   12809 (OMX_BUFFERHEADERTYPE *bufadd)
   12810 {
   12811     if (!omx) {
   12812         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   12813         return NULL;
   12814     }
   12815     if (!enabled)
   12816         return bufadd;
   12817     unsigned index = 0;
   12818     index = bufadd - m_out_mem_ptr_client;
   12819     if (index < omx->drv_ctx.op_buf.actualcount) {
   12820         return &omx->m_out_mem_ptr[index];
   12821     }
   12822     DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
   12823     return NULL;
   12824 }
   12825     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   12826 (unsigned int &buffer_size)
   12827 {
   12828     bool status = true;
   12829     pthread_mutex_lock(&omx->c_lock);
   12830     if (!enabled)
   12831         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   12832     else {
   12833         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   12834             DEBUG_PRINT_ERROR("Get buffer size failed");
   12835             status = false;
   12836             goto fail_get_buffer_size;
   12837         }
   12838     }
   12839 fail_get_buffer_size:
   12840     pthread_mutex_unlock(&omx->c_lock);
   12841     return status;
   12842 }
   12843 
   12844 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::set_buffer_req(
   12845         OMX_U32 buffer_size, OMX_U32 actual_count) {
   12846     OMX_U32 expectedSize = enabled ? buffer_size_req : omx->drv_ctx.op_buf.buffer_size;
   12847 
   12848     if (buffer_size < expectedSize) {
   12849         DEBUG_PRINT_ERROR("OP Requirements: Client size(%u) insufficient v/s requested(%u)",
   12850                 buffer_size, expectedSize);
   12851         return OMX_ErrorBadParameter;
   12852     }
   12853     if (actual_count < omx->drv_ctx.op_buf.actualcount) {
   12854         DEBUG_PRINT_ERROR("OP Requirements: Client count(%u) insufficient v/s requested(%u)",
   12855                 actual_count, omx->drv_ctx.op_buf.actualcount);
   12856         return OMX_ErrorBadParameter;
   12857     }
   12858 
   12859     bool reqs_updated = false;
   12860     if (enabled) {
   12861         // disallow changing buffer size/count while we have active allocated buffers
   12862         if (allocated_count > 0) {
   12863             DEBUG_PRINT_ERROR("Cannot change C2D buffer size from %u to %u with %d active allocations",
   12864                     buffer_size_req, buffer_size, allocated_count);
   12865             return OMX_ErrorInvalidState;
   12866         }
   12867 
   12868         buffer_size_req = buffer_size;
   12869     } else {
   12870         if (buffer_size > omx->drv_ctx.op_buf.buffer_size) {
   12871             omx->drv_ctx.op_buf.buffer_size = buffer_size;
   12872             reqs_updated = true;
   12873         }
   12874     }
   12875 
   12876     if (actual_count > omx->drv_ctx.op_buf.actualcount) {
   12877         omx->drv_ctx.op_buf.actualcount = actual_count;
   12878         reqs_updated = true;
   12879     }
   12880 
   12881     if (reqs_updated) {
   12882         omx->drv_ctx.extradata_info.count = omx->drv_ctx.op_buf.actualcount;
   12883         omx->drv_ctx.extradata_info.size = omx->drv_ctx.extradata_info.count *
   12884                 omx->drv_ctx.extradata_info.buffer_size;
   12885         return omx->set_buffer_req(&(omx->drv_ctx.op_buf));
   12886     }
   12887     return OMX_ErrorNone;
   12888 }
   12889 
   12890 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   12891         OMX_BUFFERHEADERTYPE *bufhdr)
   12892 {
   12893     unsigned int index = 0;
   12894 
   12895     if (!enabled)
   12896         return omx->free_output_buffer(bufhdr);
   12897     if (enabled && omx->is_component_secure())
   12898         return OMX_ErrorNone;
   12899     if (!allocated_count || !bufhdr) {
   12900         DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
   12901         return OMX_ErrorBadParameter;
   12902     }
   12903     index = bufhdr - m_out_mem_ptr_client;
   12904     if (index >= omx->drv_ctx.op_buf.actualcount) {
   12905         DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
   12906         return OMX_ErrorBadParameter;
   12907     }
   12908     if (pmem_fd[index] >= 0) {
   12909         munmap(pmem_baseaddress[index], buffer_size_req);
   12910         close(pmem_fd[index]);
   12911     }
   12912     pmem_fd[index] = -1;
   12913 #ifdef USE_ION
   12914     omx->free_ion_memory(&op_buf_ion_info[index]);
   12915 #endif
   12916     if (allocated_count > 0)
   12917         allocated_count--;
   12918     else
   12919         allocated_count = 0;
   12920     if (!allocated_count) {
   12921         pthread_mutex_lock(&omx->c_lock);
   12922         c2d.close();
   12923         init_members();
   12924         pthread_mutex_unlock(&omx->c_lock);
   12925     }
   12926     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   12927 }
   12928 
   12929 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   12930         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   12931 {
   12932     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12933     if (!enabled) {
   12934         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   12935         return eRet;
   12936     }
   12937     if (enabled && omx->is_component_secure()) {
   12938         DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
   12939                 omx->is_component_secure());
   12940         return OMX_ErrorUnsupportedSetting;
   12941     }
   12942     if (!bufferHdr || bytes > buffer_size_req) {
   12943         DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   12944         DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
   12945                 (unsigned int)buffer_size_req, (unsigned int)bytes);
   12946         return OMX_ErrorBadParameter;
   12947     }
   12948     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   12949         DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
   12950         return OMX_ErrorInsufficientResources;
   12951     }
   12952     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   12953     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   12954             port,appData,omx->drv_ctx.op_buf.buffer_size);
   12955     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   12956         DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
   12957         return eRet;
   12958     }
   12959     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   12960             (int)omx->drv_ctx.op_buf.actualcount) {
   12961         DEBUG_PRINT_ERROR("Invalid header index %ld",
   12962                (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
   12963         return OMX_ErrorUndefined;
   12964     }
   12965     unsigned int i = allocated_count;
   12966 #ifdef USE_ION
   12967     // Allocate color-conversion buffers as cached to improve software-reading
   12968     // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
   12969     // cache invalidation.
   12970     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   12971             buffer_size_req,buffer_alignment_req,
   12972             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   12973             ION_FLAG_CACHED);
   12974     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   12975     if (op_buf_ion_info[i].ion_device_fd < 0) {
   12976         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
   12977         return OMX_ErrorInsufficientResources;
   12978     }
   12979     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   12980             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   12981 
   12982     if (pmem_baseaddress[i] == MAP_FAILED) {
   12983         DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
   12984         close(pmem_fd[i]);
   12985         omx->free_ion_memory(&op_buf_ion_info[i]);
   12986         return OMX_ErrorInsufficientResources;
   12987     }
   12988 #endif
   12989     m_pmem_info_client[i].offset = 0;
   12990     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   12991     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   12992     m_platform_list_client[i].nEntries = 1;
   12993     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   12994     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   12995     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   12996     m_out_mem_ptr_client[i].nFilledLen = 0;
   12997     m_out_mem_ptr_client[i].nFlags = 0;
   12998     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   12999     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   13000     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   13001     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   13002     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   13003     m_out_mem_ptr_client[i].pAppPrivate = appData;
   13004     *bufferHdr = &m_out_mem_ptr_client[i];
   13005     DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr);
   13006     allocated_count++;
   13007     return eRet;
   13008 }
   13009 
   13010 bool omx_vdec::is_component_secure()
   13011 {
   13012     return secure_mode;
   13013 }
   13014 
   13015 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   13016 {
   13017     bool status = true;
   13018     if (!enabled) {
   13019         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   13020             if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   13021                     dest_color_format = (OMX_COLOR_FORMATTYPE)
   13022                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   13023                 else
   13024                     dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   13025         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){
   13026              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   13027         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_TP10_UBWC){
   13028              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m10bitCompressed;
   13029         } else
   13030             status = false;
   13031     } else {
   13032         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
   13033             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   13034             dest_color_format = ColorFormat;
   13035         } else
   13036             status = false;
   13037     }
   13038     return status;
   13039 }
   13040 
   13041 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
   13042         unsigned int index, unsigned int cmd)
   13043 {
   13044     if (!enabled) {
   13045         return OMX_ErrorNone;
   13046     }
   13047 
   13048     if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
   13049         DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
   13050         return OMX_ErrorBadParameter;
   13051     }
   13052 
   13053     struct ion_flush_data flush_data;
   13054     struct ion_custom_data custom_data;
   13055 
   13056     memset(&flush_data, 0x0, sizeof(flush_data));
   13057     memset(&custom_data, 0x0, sizeof(custom_data));
   13058 
   13059     flush_data.vaddr = pmem_baseaddress[index];
   13060     flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
   13061     flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
   13062     flush_data.length = buffer_size_req;
   13063     custom_data.cmd = cmd;
   13064     custom_data.arg = (unsigned long)&flush_data;
   13065 
   13066     DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
   13067             (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   13068             flush_data.fd, flush_data.handle, flush_data.vaddr,
   13069             flush_data.length);
   13070     int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
   13071     if (ret < 0) {
   13072         DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
   13073                 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   13074                 strerror(errno));
   13075         return OMX_ErrorUndefined;
   13076     }
   13077     return OMX_ErrorNone;
   13078 }
   13079 
   13080 void omx_vdec::buf_ref_add(int nPortIndex)
   13081 {
   13082     unsigned long i = 0;
   13083     bool buf_present = false;
   13084     long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   13085     OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   13086 
   13087     if (!dynamic_buf_mode || !out_dynamic_list) {
   13088         return;
   13089     }
   13090 
   13091     pthread_mutex_lock(&m_lock);
   13092     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13093         //check the buffer fd, offset, uv addr with list contents
   13094         //If present increment reference.
   13095         if ((out_dynamic_list[i].fd == fd) &&
   13096             (out_dynamic_list[i].offset == offset)) {
   13097                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
   13098                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13099                if (!secure_mode) {
   13100                    drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr;
   13101                }
   13102                buf_present = true;
   13103                break;
   13104         }
   13105     }
   13106     if (!buf_present) {
   13107         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13108             //search for a entry to insert details of the new buffer
   13109             if (out_dynamic_list[i].dup_fd < 0) {
   13110                 out_dynamic_list[i].fd = fd;
   13111                 out_dynamic_list[i].offset = offset;
   13112                 out_dynamic_list[i].dup_fd = dup(fd);
   13113                 out_dynamic_list[i].ref_count++;
   13114                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
   13115                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13116 
   13117                 if (!secure_mode) {
   13118                     drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   13119                             (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len,
   13120                                           PROT_READ|PROT_WRITE, MAP_SHARED,
   13121                                           drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   13122                     //mmap returns (void *)-1 on failure and sets error code in errno.
   13123                     if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) {
   13124                         DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno);
   13125                         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL;
   13126                         break;
   13127                     }
   13128                     out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr;
   13129                     out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len;
   13130                     DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   13131                 }
   13132                 break;
   13133             }
   13134         }
   13135     }
   13136    pthread_mutex_unlock(&m_lock);
   13137 }
   13138 
   13139 void omx_vdec::buf_ref_remove()
   13140 {
   13141     unsigned long i = 0;
   13142 
   13143     if (!dynamic_buf_mode || !out_dynamic_list) {
   13144         return;
   13145     }
   13146 
   13147     pthread_mutex_lock(&m_lock);
   13148     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   13149         if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) {
   13150             DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   13151             munmap(out_dynamic_list[i].buffaddr,
   13152                         out_dynamic_list[i].mapped_size);
   13153         }
   13154 
   13155          DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
   13156                  (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   13157          close(out_dynamic_list[i].dup_fd);
   13158          out_dynamic_list[i].dup_fd = -1;
   13159     }
   13160     pthread_mutex_unlock(&m_lock);
   13161 
   13162     if (out_dynamic_list) {
   13163         free(out_dynamic_list);
   13164         out_dynamic_list = NULL;
   13165     }
   13166 }
   13167 
   13168 #ifdef _MSM8974_
   13169 void omx_vdec::send_codec_config() {
   13170     if (codec_config_flag) {
   13171         unsigned long p1 = 0; // Parameter - 1
   13172         unsigned long p2 = 0; // Parameter - 2
   13173         unsigned long ident = 0;
   13174         pthread_mutex_lock(&m_lock);
   13175         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   13176         while (m_etb_q.m_size) {
   13177             m_etb_q.pop_entry(&p1,&p2,&ident);
   13178             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   13179                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   13180                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   13181                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   13182                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   13183                         omx_report_error();
   13184                     }
   13185                 } else {
   13186                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   13187                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   13188                 }
   13189             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   13190                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   13191                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   13192                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   13193                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   13194                         omx_report_error ();
   13195                     }
   13196                 } else {
   13197                     pending_input_buffers++;
   13198                     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
   13199                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   13200                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   13201                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   13202                 }
   13203             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   13204                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   13205                         (OMX_BUFFERHEADERTYPE *)p1);
   13206                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   13207             }
   13208         }
   13209         pthread_mutex_unlock(&m_lock);
   13210     }
   13211 }
   13212 #endif
   13213 
   13214 omx_vdec::perf_control::perf_control()
   13215 {
   13216     m_perf_lib = NULL;
   13217     m_perf_handle = 0;
   13218     m_perf_lock_acquire = NULL;
   13219     m_perf_lock_release = NULL;
   13220 }
   13221 
   13222 omx_vdec::perf_control::~perf_control()
   13223 {
   13224     if (m_perf_handle != 0 && m_perf_lock_release) {
   13225         DEBUG_PRINT_LOW("NOTE2: release perf lock");
   13226         m_perf_lock_release(m_perf_handle);
   13227     }
   13228     if (m_perf_lib) {
   13229         dlclose(m_perf_lib);
   13230     }
   13231 }
   13232 
   13233 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0};
   13234 
   13235 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock;
   13236 
   13237 void omx_vdec::perf_control::send_hint_to_mpctl(bool state)
   13238 {
   13239     if (load_lib() == false) {
   13240        return;
   13241     }
   13242     m_perf_lock.lock();
   13243     /* 0x4401 maps to video decode playback hint
   13244      * in perflock, enum number is 44 and state
   13245      * being sent on perflock acquire is 01 (true)
   13246      */
   13247     int arg = 0x4401;
   13248 
   13249     if (state == true) {
   13250         mpctl_obj.vid_inst_count++;
   13251     } else if (state == false) {
   13252         mpctl_obj.vid_inst_count--;
   13253     }
   13254 
   13255     if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) {
   13256         mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
   13257         mpctl_obj.vid_acquired = true;
   13258         DEBUG_PRINT_INFO("Video slvp perflock acquired");
   13259     } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) {
   13260         m_perf_lock_release(mpctl_obj.vid_disp_handle);
   13261         mpctl_obj.vid_acquired = false;
   13262         DEBUG_PRINT_INFO("Video slvp perflock released");
   13263     }
   13264     m_perf_lock.unlock();
   13265 }
   13266 
   13267 void omx_vdec::perf_control::request_cores(int frame_duration_us)
   13268 {
   13269     if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
   13270         return;
   13271     }
   13272     bool retVal = load_lib();
   13273     if (retVal && m_perf_lock_acquire && m_perf_handle == 0) {
   13274         int arg = 0x700 /*base value*/ + 2 /*cores*/;
   13275         m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
   13276         if (m_perf_handle) {
   13277             DEBUG_PRINT_HIGH("perf lock acquired");
   13278         }
   13279     }
   13280 }
   13281 
   13282 bool omx_vdec::perf_control::load_lib()
   13283 {
   13284     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
   13285     if (m_perf_lib)
   13286         return true;
   13287 
   13288     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
   13289         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
   13290         goto handle_err;
   13291     }
   13292 
   13293     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
   13294         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
   13295         goto handle_err;
   13296     } else {
   13297         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
   13298         if (m_perf_lock_acquire == NULL) {
   13299             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
   13300             goto handle_err;
   13301         }
   13302         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
   13303         if (m_perf_lock_release == NULL) {
   13304             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
   13305             goto handle_err;
   13306         }
   13307     }
   13308     return true;
   13309 
   13310 handle_err:
   13311     if (m_perf_lib) {
   13312         dlclose(m_perf_lib);
   13313     }
   13314     m_perf_lib = NULL;
   13315     return false;
   13316 }
   13317 
   13318 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
   13319                             unsigned long nMaxFrameHeight)
   13320 {
   13321 
   13322     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   13323     int ret = 0;
   13324     unsigned long min_res_buf_count = 0;
   13325 
   13326     eRet = enable_smoothstreaming();
   13327     if (eRet != OMX_ErrorNone) {
   13328          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
   13329          return eRet;
   13330      }
   13331 
   13332      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
   13333              nMaxFrameWidth,
   13334              nMaxFrameHeight);
   13335      m_smoothstreaming_mode = true;
   13336      m_smoothstreaming_width = nMaxFrameWidth;
   13337      m_smoothstreaming_height = nMaxFrameHeight;
   13338 
   13339      //Get upper limit buffer count for min supported resolution
   13340      struct v4l2_format fmt;
   13341      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   13342      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
   13343      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
   13344      fmt.fmt.pix_mp.pixelformat = output_capability;
   13345 
   13346      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   13347      if (ret) {
   13348          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
   13349                            m_decoder_capability.min_height,
   13350                            m_decoder_capability.min_width);
   13351          return OMX_ErrorUnsupportedSetting;
   13352      }
   13353 
   13354      eRet = get_buffer_req(&drv_ctx.op_buf);
   13355      if (eRet != OMX_ErrorNone) {
   13356          DEBUG_PRINT_ERROR("failed to get_buffer_req");
   13357          return eRet;
   13358      }
   13359 
   13360      min_res_buf_count = drv_ctx.op_buf.mincount;
   13361      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
   13362                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
   13363 
   13364      m_extradata_info.output_crop_rect.nLeft = 0;
   13365      m_extradata_info.output_crop_rect.nTop = 0;
   13366      m_extradata_info.output_crop_rect.nWidth = m_smoothstreaming_width;
   13367      m_extradata_info.output_crop_rect.nHeight = m_smoothstreaming_height;
   13368 
   13369      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
   13370                        m_smoothstreaming_width, m_smoothstreaming_height);
   13371      eRet = is_video_session_supported();
   13372      if (eRet != OMX_ErrorNone) {
   13373          DEBUG_PRINT_ERROR("video session is not supported");
   13374          return eRet;
   13375      }
   13376 
   13377      //Get upper limit buffer size for max smooth streaming resolution set
   13378      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   13379      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   13380      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   13381      fmt.fmt.pix_mp.pixelformat = output_capability;
   13382      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   13383      if (ret) {
   13384          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
   13385          return OMX_ErrorUnsupportedSetting;
   13386      }
   13387 
   13388      eRet = get_buffer_req(&drv_ctx.op_buf);
   13389      if (eRet != OMX_ErrorNone) {
   13390          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
   13391          return eRet;
   13392      }
   13393      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
   13394                      (unsigned int)drv_ctx.op_buf.buffer_size);
   13395 
   13396      drv_ctx.op_buf.mincount = min_res_buf_count;
   13397      drv_ctx.op_buf.actualcount = min_res_buf_count;
   13398      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
   13399      eRet = set_buffer_req(&drv_ctx.op_buf);
   13400      if (eRet != OMX_ErrorNone) {
   13401          DEBUG_PRINT_ERROR("failed to set_buffer_req");
   13402          return eRet;
   13403      }
   13404 
   13405      eRet = get_buffer_req(&drv_ctx.op_buf);
   13406      if (eRet != OMX_ErrorNone) {
   13407          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
   13408          return eRet;
   13409      }
   13410      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
   13411                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
   13412      return eRet;
   13413 }
   13414 
   13415 //static
   13416 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
   13417 
   13418 #ifndef FLEXYUV_SUPPORTED
   13419     return OMX_ErrorUndefined;
   13420 #else
   13421 
   13422     if (pParam == NULL) {
   13423         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
   13424         return OMX_ErrorBadParameter;
   13425     }
   13426 
   13427     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
   13428 
   13429     MediaImage *img = &(params->sMediaImage);
   13430     switch(params->eColorFormat) {
   13431         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   13432         {
   13433             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   13434             img->mNumPlanes = 3;
   13435             // mWidth and mHeight represent the W x H of the largest plane
   13436             // In our case, this happens to be the Stride x Scanlines of Y plane
   13437             img->mWidth = params->nFrameWidth;
   13438             img->mHeight = params->nFrameHeight;
   13439             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13440             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
   13441             img->mBitDepth = 8;
   13442             //Plane 0 (Y)
   13443             img->mPlane[MediaImage::Y].mOffset = 0;
   13444             img->mPlane[MediaImage::Y].mColInc = 1;
   13445             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
   13446             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
   13447             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
   13448             //Plane 1 (U)
   13449             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
   13450             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
   13451             img->mPlane[MediaImage::U].mRowInc =
   13452                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13453             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
   13454             img->mPlane[MediaImage::U].mVertSubsampling = 2;
   13455             //Plane 2 (V)
   13456             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
   13457             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
   13458             img->mPlane[MediaImage::V].mRowInc =
   13459                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   13460             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
   13461             img->mPlane[MediaImage::V].mVertSubsampling = 2;
   13462             break;
   13463         }
   13464 
   13465         case OMX_COLOR_FormatYUV420Planar:
   13466         case OMX_COLOR_FormatYUV420SemiPlanar:
   13467             // We need not describe the standard OMX linear formats as these are
   13468             // understood by client. Fail this deliberately to let client fill-in
   13469             return OMX_ErrorUnsupportedSetting;
   13470 
   13471         default:
   13472             // Rest all formats which are non-linear cannot be described
   13473             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
   13474             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   13475             return OMX_ErrorNone;
   13476     };
   13477 
   13478     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
   13479     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
   13480     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
   13481     for (size_t i = 0; i < img->mNumPlanes; ++i) {
   13482         DEBUG_PRINT_LOW("  Plane[%zu] : offset=%d / xStep=%d / yStep = %d",
   13483                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
   13484     }
   13485     return OMX_ErrorNone;
   13486 #endif //FLEXYUV_SUPPORTED
   13487 }
   13488 
   13489 void omx_vdec::prefetchNewBuffers() {
   13490 
   13491     struct v4l2_decoder_cmd dec;
   13492     uint32_t prefetch_count;
   13493     uint32_t prefetch_size;
   13494     uint32_t want_size;
   13495     uint32_t have_size;
   13496     int color_fmt, rc;
   13497     uint32_t new_calculated_size;
   13498     uint32_t new_buffer_size;
   13499     uint32_t new_buffer_count;
   13500     uint32_t old_buffer_size;
   13501     uint32_t old_buffer_count;
   13502 
   13503     memset((void *)&dec, 0 , sizeof(dec));
   13504     DEBUG_PRINT_LOW("Old size : %zu, count : %d, width : %u, height : %u\n",
   13505             drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount,
   13506             drv_ctx.video_resolution.frame_width,
   13507             drv_ctx.video_resolution.frame_height);
   13508     dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT;
   13509     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   13510         DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno);
   13511     } else {
   13512         DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n",
   13513                 dec.raw.data[0], dec.raw.data[1]);
   13514     }
   13515 
   13516     switch ((int)drv_ctx.output_format) {
   13517     case VDEC_YUV_FORMAT_NV12:
   13518         color_fmt = COLOR_FMT_NV12;
   13519         break;
   13520     case VDEC_YUV_FORMAT_NV12_UBWC:
   13521         color_fmt = COLOR_FMT_NV12_UBWC;
   13522         break;
   13523     case VDEC_YUV_FORMAT_NV12_TP10_UBWC:
   13524         color_fmt = COLOR_FMT_NV12_BPP10_UBWC;
   13525         break;
   13526     default:
   13527         color_fmt = -1;
   13528         DEBUG_PRINT_HIGH("Color format : %x not supported for secure memory prefetching\n", drv_ctx.output_format);
   13529         return;
   13530     }
   13531 
   13532     new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height);
   13533     DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n",
   13534             m_reconfig_width, m_reconfig_height, new_calculated_size);
   13535     new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size;
   13536     new_buffer_count = dec.raw.data[1];
   13537     old_buffer_size = drv_ctx.op_buf.buffer_size;
   13538     old_buffer_count = drv_ctx.op_buf.actualcount;
   13539 
   13540     new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count;
   13541 
   13542     prefetch_count = new_buffer_count;
   13543     prefetch_size = new_buffer_size - old_buffer_size;
   13544     want_size = new_buffer_size * new_buffer_count;
   13545     have_size = old_buffer_size * old_buffer_count;
   13546 
   13547     if (want_size > have_size) {
   13548         DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size);
   13549         DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size);
   13550 
   13551         int ion_fd = open(MEM_DEVICE, O_RDONLY);
   13552         if (ion_fd < 0) {
   13553             DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd);
   13554             return;
   13555         }
   13556 
   13557         struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data));
   13558         struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data));
   13559         struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions));
   13560         size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count);
   13561 
   13562         if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) {
   13563             DEBUG_PRINT_ERROR("prefetch data allocation failed");
   13564             goto prefetch_exit;
   13565         }
   13566 
   13567         for (uint32_t i = 0; i < prefetch_count; i++) {
   13568             sizes[i] = prefetch_size;
   13569         }
   13570 
   13571         regions[0].nr_sizes = prefetch_count;
   13572         regions[0].sizes = sizes;
   13573         regions[0].vmid = ION_FLAG_CP_PIXEL;
   13574 
   13575         prefetch_data->nr_regions = 1;
   13576         prefetch_data->regions = regions;
   13577         prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
   13578 
   13579         custom_data->cmd = ION_IOC_PREFETCH;
   13580         custom_data->arg = (unsigned long )prefetch_data;
   13581 
   13582         rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data);
   13583         if (rc) {
   13584             DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno);
   13585         }
   13586 
   13587 prefetch_exit:
   13588         close(ion_fd);
   13589         free(sizes);
   13590         free(regions);
   13591         free(prefetch_data);
   13592         free(custom_data);
   13593     }
   13594 }
   13595 
   13596 
   13597 // No code beyond this !
   13598 
   13599 // inline import of vendor-extensions implementation
   13600 #include "omx_vdec_extensions.hpp"
   13601