Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2016, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 
     29 /*============================================================================
     30                             O p e n M A X   w r a p p e r s
     31                              O p e n  M A X   C o r e
     32 
     33   This module contains the implementation of the OpenMAX core & component.
     34 
     35 *//*========================================================================*/
     36 
     37 //////////////////////////////////////////////////////////////////////////////
     38 //                             Include Files
     39 //////////////////////////////////////////////////////////////////////////////
     40 
     41 #define __STDC_FORMAT_MACROS
     42 #include <inttypes.h>
     43 
     44 #include <string.h>
     45 #include <pthread.h>
     46 #include <sys/prctl.h>
     47 #include <stdlib.h>
     48 #include <unistd.h>
     49 #include <errno.h>
     50 #include "omx_vdec.h"
     51 #include <fcntl.h>
     52 #include <limits.h>
     53 #include <stdlib.h>
     54 #include <media/hardware/HardwareAPI.h>
     55 #include <media/msm_media_info.h>
     56 #include <sys/eventfd.h>
     57 #include <nativebase/nativebase.h>
     58 
     59 #ifndef _ANDROID_
     60 #include <sys/ioctl.h>
     61 #include <sys/mman.h>
     62 #endif //_ANDROID_
     63 
     64 #ifdef _ANDROID_
     65 #include <cutils/properties.h>
     66 #undef USE_EGL_IMAGE_GPU
     67 #endif
     68 
     69 #include <qdMetaData.h>
     70 
     71 #ifdef ANDROID_JELLYBEAN_MR2
     72 #include "QComOMXMetadata.h"
     73 #endif
     74 
     75 #ifdef USE_EGL_IMAGE_GPU
     76 #include <EGL/egl.h>
     77 #include <EGL/eglQCOM.h>
     78 #define EGL_BUFFER_HANDLE 0x4F00
     79 #define EGL_BUFFER_OFFSET 0x4F01
     80 #endif
     81 
     82 #define BUFFER_LOG_LOC "/data/misc/media"
     83 
     84 #ifdef OUTPUT_EXTRADATA_LOG
     85 FILE *outputExtradataFile;
     86 char output_extradata_filename [] = "/data/misc/media/extradata";
     87 #endif
     88 
     89 #define DEFAULT_FPS 30
     90 #define MAX_SUPPORTED_FPS 120
     91 #define DEFAULT_WIDTH_ALIGNMENT 128
     92 #define DEFAULT_HEIGHT_ALIGNMENT 32
     93 
     94 #define VC1_SP_MP_START_CODE        0xC5000000
     95 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     96 #define VC1_AP_SEQ_START_CODE       0x0F010000
     97 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
     98 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
     99 #define VC1_SIMPLE_PROFILE          0
    100 #define VC1_MAIN_PROFILE            1
    101 #define VC1_ADVANCE_PROFILE         3
    102 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
    103 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
    104 #define VC1_STRUCT_C_LEN            4
    105 #define VC1_STRUCT_C_POS            8
    106 #define VC1_STRUCT_A_POS            12
    107 #define VC1_STRUCT_B_POS            24
    108 #define VC1_SEQ_LAYER_SIZE          36
    109 #define POLL_TIMEOUT 0x7fffffff
    110 
    111 #define MEM_DEVICE "/dev/ion"
    112 
    113 #ifdef _ANDROID_
    114 extern "C" {
    115 #include<utils/Log.h>
    116 }
    117 #endif//_ANDROID_
    118 
    119 #define SZ_4K 0x1000
    120 #define SZ_1M 0x100000
    121 
    122 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    123 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    124 #define EXTRADATA_IDX(__num_planes) ((__num_planes) ? (__num_planes) - 1 : 0)
    125 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
    126 
    127 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA | OMX_DISPLAY_INFO_EXTRADATA)
    128 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
    129 
    130 #ifndef ION_FLAG_CP_BITSTREAM
    131 #define ION_FLAG_CP_BITSTREAM 0
    132 #endif
    133 
    134 #ifndef ION_FLAG_CP_PIXEL
    135 #define ION_FLAG_CP_PIXEL 0
    136 #endif
    137 
    138 #ifdef MASTER_SIDE_CP
    139 #define MEM_HEAP_ID ION_SECURE_HEAP_ID
    140 #define SECURE_ALIGN SZ_4K
    141 #define SECURE_FLAGS_INPUT_BUFFER (ION_SECURE | ION_FLAG_CP_BITSTREAM)
    142 #define SECURE_FLAGS_OUTPUT_BUFFER (ION_SECURE | ION_FLAG_CP_PIXEL)
    143 #else //SLAVE_SIDE_CP
    144 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    145 #define SECURE_ALIGN SZ_1M
    146 #define SECURE_FLAGS_INPUT_BUFFER ION_SECURE
    147 #define SECURE_FLAGS_OUTPUT_BUFFER ION_SECURE
    148 #endif
    149 
    150 static OMX_U32 maxSmoothStreamingWidth = 1920;
    151 static OMX_U32 maxSmoothStreamingHeight = 1088;
    152 
    153 void* async_message_thread (void *input)
    154 {
    155     OMX_BUFFERHEADERTYPE *buffer;
    156     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    157     struct pollfd pfds[2];
    158     struct v4l2_buffer v4l2_buf;
    159     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    160     struct v4l2_event dqevent;
    161     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
    162     pfds[0].events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    163     pfds[1].events = POLLIN | POLLERR;
    164     pfds[0].fd = omx->drv_ctx.video_driver_fd;
    165     pfds[1].fd = omx->m_poll_efd;
    166     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    167     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
    168     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
    169     while (!omx->async_thread_force_stop) {
    170         rc = poll(pfds, 2, POLL_TIMEOUT);
    171         if (!rc) {
    172             DEBUG_PRINT_ERROR("Poll timedout");
    173             break;
    174         } else if (rc < 0 && errno != EINTR && errno != EAGAIN) {
    175             DEBUG_PRINT_ERROR("Error while polling: %d, errno = %d", rc, errno);
    176             break;
    177         }
    178         if ((pfds[1].revents & POLLIN) || (pfds[1].revents & POLLERR)) {
    179             DEBUG_PRINT_HIGH("async_message_thread interrupted to be exited");
    180             break;
    181         }
    182         if ((pfds[0].revents & POLLIN) || (pfds[0].revents & POLLRDNORM)) {
    183             struct vdec_msginfo vdec_msg;
    184             memset(&vdec_msg, 0, sizeof(vdec_msg));
    185             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    186             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    187             v4l2_buf.length = omx->drv_ctx.num_planes;
    188             v4l2_buf.m.planes = plane;
    189             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    190                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    191                 vdec_msg.status_code=VDEC_S_SUCCESS;
    192                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    193                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
    194                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
    195                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    196                     (uint64_t)v4l2_buf.timestamp.tv_usec;
    197                 if (vdec_msg.msgdata.output_frame.len) {
    198                     vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
    199                     vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
    200                     vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
    201                     vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
    202                     vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
    203                     vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
    204                 }
    205                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    206                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    207                     break;
    208                 }
    209             }
    210         }
    211         if ((pfds[0].revents & POLLOUT) || (pfds[0].revents & POLLWRNORM)) {
    212             struct vdec_msginfo vdec_msg;
    213             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    214             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    215             v4l2_buf.length = 1;
    216             v4l2_buf.m.planes = plane;
    217             while (!ioctl(pfds[0].fd, VIDIOC_DQBUF, &v4l2_buf)) {
    218                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
    219                 vdec_msg.status_code=VDEC_S_SUCCESS;
    220                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    221                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    222                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    223                     break;
    224                 }
    225             }
    226         }
    227         if (pfds[0].revents & POLLPRI) {
    228             rc = ioctl(pfds[0].fd, VIDIOC_DQEVENT, &dqevent);
    229             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
    230                 struct vdec_msginfo vdec_msg;
    231                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    232 
    233                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    234                 vdec_msg.status_code=VDEC_S_SUCCESS;
    235                 vdec_msg.msgdata.output_frame.picsize.frame_height = ptr[0];
    236                 vdec_msg.msgdata.output_frame.picsize.frame_width = ptr[1];
    237                 DEBUG_PRINT_HIGH("VIDC Port Reconfig received insufficient");
    238                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    239                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    240                     break;
    241                 }
    242             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT ) {
    243                 struct vdec_msginfo vdec_msg;
    244                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    245                 vdec_msg.status_code=VDEC_S_SUCCESS;
    246                 omx->dpb_bit_depth = dqevent.u.data[0];
    247                 DEBUG_PRINT_HIGH("VIDC Port Reconfig Bitdepth change - %d", dqevent.u.data[0]);
    248                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    249                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    250                     break;
    251                 }
    252             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    253                 struct vdec_msginfo vdec_msg;
    254                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
    255                 vdec_msg.status_code=VDEC_S_SUCCESS;
    256                 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
    257                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    258                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    259                     break;
    260                 }
    261                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
    262                 vdec_msg.status_code=VDEC_S_SUCCESS;
    263                 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
    264                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    265                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    266                     break;
    267                 }
    268             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
    269                 struct vdec_msginfo vdec_msg;
    270                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
    271                 vdec_msg.status_code=VDEC_S_SUCCESS;
    272                 DEBUG_PRINT_ERROR("HW Overload received");
    273                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    274                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    275                     break;
    276                 }
    277             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
    278                 struct vdec_msginfo vdec_msg;
    279                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
    280                 vdec_msg.status_code=VDEC_S_SUCCESS;
    281                 DEBUG_PRINT_ERROR("HW Unsupported received");
    282                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    283                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    284                     break;
    285                 }
    286             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    287                 struct vdec_msginfo vdec_msg;
    288                 vdec_msg.msgcode = VDEC_MSG_EVT_HW_ERROR;
    289                 vdec_msg.status_code = VDEC_S_SUCCESS;
    290                 DEBUG_PRINT_HIGH("SYS Error Recieved");
    291                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    292                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    293                     break;
    294                 }
    295             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
    296                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    297 
    298                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
    299             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
    300                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    301                 struct vdec_msginfo vdec_msg;
    302 
    303                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
    304 
    305                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    306                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    307                 v4l2_buf.length = omx->drv_ctx.num_planes;
    308                 v4l2_buf.m.planes = plane;
    309                 v4l2_buf.index = ptr[5];
    310                 v4l2_buf.flags = 0;
    311 
    312                 vdec_msg.msgcode = VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    313                 vdec_msg.status_code = VDEC_S_SUCCESS;
    314                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
    315                 vdec_msg.msgdata.output_frame.len = 0;
    316                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
    317                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
    318                     (uint64_t)ptr[4];
    319                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    320                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
    321                     break;
    322                 }
    323             } else {
    324                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
    325                 continue;
    326             }
    327         }
    328     }
    329     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
    330     return NULL;
    331 }
    332 
    333 void* message_thread(void *input)
    334 {
    335     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    336     unsigned char id;
    337     int n;
    338 
    339     fd_set readFds;
    340     int res = 0;
    341     struct timeval tv;
    342 
    343     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
    344     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
    345     while (!omx->message_thread_stop) {
    346 
    347         tv.tv_sec = 2;
    348         tv.tv_usec = 0;
    349 
    350         FD_ZERO(&readFds);
    351         FD_SET(omx->m_pipe_in, &readFds);
    352 
    353         res = select(omx->m_pipe_in + 1, &readFds, NULL, NULL, &tv);
    354         if (res < 0) {
    355             DEBUG_PRINT_ERROR("select() ERROR: %s", strerror(errno));
    356             continue;
    357         } else if (res == 0 /*timeout*/ || omx->message_thread_stop) {
    358             continue;
    359         }
    360 
    361         n = read(omx->m_pipe_in, &id, 1);
    362 
    363         if (0 == n) {
    364             break;
    365         }
    366 
    367         if (1 == n) {
    368             omx->process_event_cb(omx, id);
    369         }
    370 
    371         if ((n < 0) && (errno != EINTR)) {
    372             DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    373             break;
    374         }
    375     }
    376     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
    377     return 0;
    378 }
    379 
    380 void post_message(omx_vdec *omx, unsigned char id)
    381 {
    382     int ret_value;
    383     DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
    384     ret_value = write(omx->m_pipe_out, &id, 1);
    385     if (ret_value <= 0) {
    386         DEBUG_PRINT_ERROR("post_message to pipe failed : %s", strerror(errno));
    387     } else {
    388         DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    389     }
    390 }
    391 
    392 // omx_cmd_queue destructor
    393 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    394 {
    395     // Nothing to do
    396 }
    397 
    398 // omx cmd queue constructor
    399 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    400 {
    401     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    402 }
    403 
    404 // omx cmd queue insert
    405 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
    406 {
    407     bool ret = true;
    408     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    409         m_q[m_write].id       = id;
    410         m_q[m_write].param1   = p1;
    411         m_q[m_write].param2   = p2;
    412         m_write++;
    413         m_size ++;
    414         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    415             m_write = 0;
    416         }
    417     } else {
    418         ret = false;
    419         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
    420     }
    421     return ret;
    422 }
    423 
    424 // omx cmd queue pop
    425 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
    426 {
    427     bool ret = true;
    428     if (m_size > 0) {
    429         *id = m_q[m_read].id;
    430         *p1 = m_q[m_read].param1;
    431         *p2 = m_q[m_read].param2;
    432         // Move the read pointer ahead
    433         ++m_read;
    434         --m_size;
    435         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    436             m_read = 0;
    437         }
    438     } else {
    439         ret = false;
    440     }
    441     return ret;
    442 }
    443 
    444 // Retrieve the first mesg type in the queue
    445 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    446 {
    447     return m_q[m_read].id;
    448 }
    449 
    450 #ifdef _ANDROID_
    451 omx_vdec::ts_arr_list::ts_arr_list()
    452 {
    453     //initialize timestamps array
    454     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    455 }
    456 omx_vdec::ts_arr_list::~ts_arr_list()
    457 {
    458     //free m_ts_arr_list?
    459 }
    460 
    461 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
    462 {
    463     bool ret = true;
    464     bool duplicate_ts = false;
    465     int idx = 0;
    466 
    467     //insert at the first available empty location
    468     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    469         if (!m_ts_arr_list[idx].valid) {
    470             //found invalid or empty entry, save timestamp
    471             m_ts_arr_list[idx].valid = true;
    472             m_ts_arr_list[idx].timestamp = ts;
    473             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    474                     ts, idx);
    475             break;
    476         }
    477     }
    478 
    479     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
    480         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    481         ret = false;
    482     }
    483     return ret;
    484 }
    485 
    486 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    487 {
    488     bool ret = true;
    489     int min_idx = -1;
    490     OMX_TICKS min_ts = 0;
    491     int idx = 0;
    492 
    493     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    494 
    495         if (m_ts_arr_list[idx].valid) {
    496             //found valid entry, save index
    497             if (min_idx < 0) {
    498                 //first valid entry
    499                 min_ts = m_ts_arr_list[idx].timestamp;
    500                 min_idx = idx;
    501             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
    502                 min_ts = m_ts_arr_list[idx].timestamp;
    503                 min_idx = idx;
    504             }
    505         }
    506 
    507     }
    508 
    509     if (min_idx < 0) {
    510         //no valid entries found
    511         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    512         ts = 0;
    513         ret = false;
    514     } else {
    515         ts = m_ts_arr_list[min_idx].timestamp;
    516         m_ts_arr_list[min_idx].valid = false;
    517         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    518                 ts, min_idx);
    519     }
    520 
    521     return ret;
    522 
    523 }
    524 
    525 
    526 bool omx_vdec::ts_arr_list::reset_ts_list()
    527 {
    528     bool ret = true;
    529     int idx = 0;
    530 
    531     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    532     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    533         m_ts_arr_list[idx].valid = false;
    534     }
    535     return ret;
    536 }
    537 #endif
    538 
    539 // factory function executed by the core to create instances
    540 void *get_omx_component_factory_fn(void)
    541 {
    542     return (new omx_vdec);
    543 }
    544 
    545 #ifdef _ANDROID_
    546 #ifdef USE_ION
    547 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
    548         ion_user_handle_t handle, int ionMapfd)
    549 {
    550     (void) devicefd;
    551     (void) size;
    552     (void) base;
    553     (void) handle;
    554     (void) ionMapfd;
    555     //    ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
    556 }
    557 #else
    558 VideoHeap::VideoHeap(int fd, size_t size, void* base)
    559 {
    560     // dup file descriptor, map once, use pmem
    561     init(dup(fd), base, size, 0 , MEM_DEVICE);
    562 }
    563 #endif
    564 #endif // _ANDROID_
    565 /* ======================================================================
    566    FUNCTION
    567    omx_vdec::omx_vdec
    568 
    569    DESCRIPTION
    570    Constructor
    571 
    572    PARAMETERS
    573    None
    574 
    575    RETURN VALUE
    576    None.
    577    ========================================================================== */
    578 omx_vdec::omx_vdec(): m_error_propogated(false),
    579     m_state(OMX_StateInvalid),
    580     m_app_data(NULL),
    581     m_inp_mem_ptr(NULL),
    582     m_out_mem_ptr(NULL),
    583     input_flush_progress (false),
    584     output_flush_progress (false),
    585     input_use_buffer (false),
    586     output_use_buffer (false),
    587     ouput_egl_buffers(false),
    588     m_use_output_pmem(OMX_FALSE),
    589     m_out_mem_region_smi(OMX_FALSE),
    590     m_out_pvt_entry_pmem(OMX_FALSE),
    591     pending_input_buffers(0),
    592     pending_output_buffers(0),
    593     m_out_bm_count(0),
    594     m_inp_bm_count(0),
    595     m_inp_bPopulated(OMX_FALSE),
    596     m_out_bPopulated(OMX_FALSE),
    597     m_flags(0),
    598 #ifdef _ANDROID_
    599     m_heap_ptr(NULL),
    600 #endif
    601     m_inp_bEnabled(OMX_TRUE),
    602     m_out_bEnabled(OMX_TRUE),
    603     m_in_alloc_cnt(0),
    604     m_platform_list(NULL),
    605     m_platform_entry(NULL),
    606     m_pmem_info(NULL),
    607     h264_parser(NULL),
    608     arbitrary_bytes (true),
    609     psource_frame (NULL),
    610     pdest_frame (NULL),
    611     m_inp_heap_ptr (NULL),
    612     m_phdr_pmem_ptr(NULL),
    613     m_heap_inp_bm_count (0),
    614     codec_type_parse ((codec_type)0),
    615     first_frame_meta (true),
    616     frame_count (0),
    617     nal_count (0),
    618     nal_length(0),
    619     look_ahead_nal (false),
    620     first_frame(0),
    621     first_buffer(NULL),
    622     first_frame_size (0),
    623     m_device_file_ptr(NULL),
    624     m_vc1_profile((vc1_profile_type)0),
    625     h264_last_au_ts(LLONG_MAX),
    626     h264_last_au_flags(0),
    627     m_disp_hor_size(0),
    628     m_disp_vert_size(0),
    629     prev_ts(LLONG_MAX),
    630     prev_ts_actual(LLONG_MAX),
    631     rst_prev_ts(true),
    632     frm_int(0),
    633     in_reconfig(false),
    634     m_display_id(NULL),
    635     client_extradata(0),
    636     m_reject_avc_1080p_mp (0),
    637 #ifdef _ANDROID_
    638     m_enable_android_native_buffers(OMX_FALSE),
    639     m_use_android_native_buffers(OMX_FALSE),
    640 #endif
    641     m_desc_buffer_ptr(NULL),
    642     secure_mode(false),
    643     allocate_native_handle(false),
    644     m_other_extradata(NULL),
    645     m_profile(0),
    646     client_set_fps(false),
    647     m_last_rendered_TS(-1),
    648     m_queued_codec_config_count(0),
    649     current_perf_level(V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL),
    650     secure_scaling_to_non_secure_opb(false),
    651     m_force_compressed_for_dpb(false)
    652 {
    653     m_pipe_in = -1;
    654     m_pipe_out = -1;
    655     m_poll_efd = -1;
    656     drv_ctx.video_driver_fd = -1;
    657     drv_ctx.extradata_info.ion.fd_ion_data.fd = -1;
    658     /* Assumption is that , to begin with , we have all the frames with decoder */
    659     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
    660     memset(&m_debug,0,sizeof(m_debug));
    661 #ifdef _ANDROID_
    662     char property_value[PROPERTY_VALUE_MAX] = {0};
    663     property_get("vidc.debug.level", property_value, "1");
    664     debug_level = atoi(property_value);
    665     property_value[0] = '\0';
    666 
    667     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
    668 
    669     property_get("vidc.dec.debug.perf", property_value, "0");
    670     perf_flag = atoi(property_value);
    671     if (perf_flag) {
    672         DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
    673         dec_time.start();
    674         proc_frms = latency = 0;
    675     }
    676     prev_n_filled_len = 0;
    677     property_value[0] = '\0';
    678     property_get("vidc.dec.debug.ts", property_value, "0");
    679     m_debug_timestamp = atoi(property_value);
    680     DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
    681     if (m_debug_timestamp) {
    682         time_stamp_dts.set_timestamp_reorder_mode(true);
    683         time_stamp_dts.enable_debug_print(true);
    684     }
    685 
    686     property_value[0] = '\0';
    687     property_get("vidc.dec.debug.concealedmb", property_value, "0");
    688     m_debug_concealedmb = atoi(property_value);
    689     DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
    690 
    691     property_value[0] = '\0';
    692     property_get("vidc.dec.profile.check", property_value, "0");
    693     m_reject_avc_1080p_mp = atoi(property_value);
    694     DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
    695 
    696     property_value[0] = '\0';
    697     property_get("vidc.dec.log.in", property_value, "0");
    698     m_debug.in_buffer_log = atoi(property_value);
    699 
    700     property_value[0] = '\0';
    701     property_get("vidc.dec.log.out", property_value, "0");
    702     m_debug.out_buffer_log = atoi(property_value);
    703     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    704 
    705     property_value[0] = '\0';
    706     property_get("vidc.dec.meta.log.out", property_value, "0");
    707     m_debug.out_meta_buffer_log = atoi(property_value);
    708     snprintf(m_debug.log_loc, PROPERTY_VALUE_MAX, "%s", BUFFER_LOG_LOC);
    709 
    710     property_value[0] = '\0';
    711     property_get("vidc.log.loc", property_value, "");
    712     if (*property_value)
    713         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
    714 
    715     property_value[0] = '\0';
    716     property_get("vidc.dec.120fps.enabled", property_value, "0");
    717 
    718     //if this feature is not enabled then reset this value -ve
    719     if(atoi(property_value)) {
    720         DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
    721         m_last_rendered_TS = 0;
    722     }
    723 
    724     property_value[0] = '\0';
    725     property_get("vidc.dec.debug.dyn.disabled", property_value, "0");
    726     m_disable_dynamic_buf_mode = atoi(property_value);
    727     DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode);
    728 
    729 #ifdef _UBWC_
    730     property_value[0] = '\0';
    731     property_get("debug.gralloc.gfx_ubwc_disable", property_value, "0");
    732     m_disable_ubwc_mode = atoi(property_value);
    733     DEBUG_PRINT_HIGH("UBWC mode is %s", m_disable_ubwc_mode ? "disabled" : "enabled");
    734 #else
    735     m_disable_ubwc_mode = true;
    736 #endif
    737 #endif
    738     memset(&m_cmp,0,sizeof(m_cmp));
    739     memset(&m_cb,0,sizeof(m_cb));
    740     memset (&drv_ctx,0,sizeof(drv_ctx));
    741     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    742     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    743     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
    744     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
    745     memset(&m_client_color_space, 0, sizeof(DescribeColorAspectsParams));
    746     memset(&m_internal_color_space, 0, sizeof(DescribeColorAspectsParams));
    747     m_demux_entries = 0;
    748     msg_thread_id = 0;
    749     async_thread_id = 0;
    750     msg_thread_created = false;
    751     async_thread_created = false;
    752     async_thread_force_stop = false;
    753     message_thread_stop = false;
    754 #ifdef _ANDROID_ICS_
    755     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    756 #endif
    757     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
    758 
    759     /* invalidate m_frame_pack_arrangement */
    760     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
    761     m_frame_pack_arrangement.cancel_flag = 1;
    762 
    763     drv_ctx.timestamp_adjust = false;
    764     m_vendor_config.pData = NULL;
    765     pthread_mutex_init(&m_lock, NULL);
    766     pthread_mutex_init(&c_lock, NULL);
    767     pthread_mutex_init(&buf_lock, NULL);
    768     sem_init(&m_cmd_lock,0,0);
    769     sem_init(&m_safe_flush, 0, 0);
    770     streaming[CAPTURE_PORT] =
    771         streaming[OUTPUT_PORT] = false;
    772 #ifdef _ANDROID_
    773     char extradata_value[PROPERTY_VALUE_MAX] = {0};
    774     property_get("vidc.dec.debug.extradata", extradata_value, "0");
    775     m_debug_extradata = atoi(extradata_value);
    776     DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
    777 #endif
    778     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    779     client_buffers.set_vdec_client(this);
    780     dynamic_buf_mode = false;
    781     out_dynamic_list = NULL;
    782     is_down_scalar_enabled = false;
    783     m_downscalar_width = 0;
    784     m_downscalar_height = 0;
    785     m_force_down_scalar = 0;
    786     m_reconfig_height = 0;
    787     m_reconfig_width = 0;
    788     m_smoothstreaming_mode = false;
    789     m_smoothstreaming_width = 0;
    790     m_smoothstreaming_height = 0;
    791     m_decode_order_mode = false;
    792     is_q6_platform = false;
    793     m_perf_control.send_hint_to_mpctl(true);
    794     m_input_pass_buffer_fd = false;
    795     m_client_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    796     m_client_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    797     m_client_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    798     m_client_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    799     m_client_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    800 
    801     m_internal_color_space.nPortIndex = (OMX_U32)OMX_CORE_OUTPUT_PORT_INDEX;
    802     m_internal_color_space.sAspects.mRange =  ColorAspects::RangeUnspecified;
    803     m_internal_color_space.sAspects.mPrimaries = ColorAspects::PrimariesUnspecified;
    804     m_internal_color_space.sAspects.mMatrixCoeffs = ColorAspects::MatrixUnspecified;
    805     m_internal_color_space.sAspects.mTransfer = ColorAspects::TransferUnspecified;
    806     m_internal_color_space.nSize = sizeof(DescribeColorAspectsParams);
    807 }
    808 
    809 static const int event_type[] = {
    810     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    811     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
    812     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
    813     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_BITDEPTH_CHANGED_INSUFFICIENT,
    814     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
    815     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
    816     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
    817     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
    818     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
    819 };
    820 
    821 static OMX_ERRORTYPE subscribe_to_events(int fd)
    822 {
    823     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    824     struct v4l2_event_subscription sub;
    825     int array_sz = sizeof(event_type)/sizeof(int);
    826     int i,rc;
    827     if (fd < 0) {
    828         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    829         return OMX_ErrorBadParameter;
    830     }
    831 
    832     for (i = 0; i < array_sz; ++i) {
    833         memset(&sub, 0, sizeof(sub));
    834         sub.type = event_type[i];
    835         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    836         if (rc) {
    837             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    838             break;
    839         }
    840     }
    841     if (i < array_sz) {
    842         for (--i; i >=0 ; i--) {
    843             memset(&sub, 0, sizeof(sub));
    844             sub.type = event_type[i];
    845             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    846             if (rc)
    847                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    848         }
    849         eRet = OMX_ErrorNotImplemented;
    850     }
    851     return eRet;
    852 }
    853 
    854 
    855 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    856 {
    857     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    858     struct v4l2_event_subscription sub;
    859     int array_sz = sizeof(event_type)/sizeof(int);
    860     int i,rc;
    861     if (fd < 0) {
    862         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    863         return OMX_ErrorBadParameter;
    864     }
    865 
    866     for (i = 0; i < array_sz; ++i) {
    867         memset(&sub, 0, sizeof(sub));
    868         sub.type = event_type[i];
    869         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    870         if (rc) {
    871             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    872             break;
    873         }
    874     }
    875     return eRet;
    876 }
    877 
    878 /* ======================================================================
    879    FUNCTION
    880    omx_vdec::~omx_vdec
    881 
    882    DESCRIPTION
    883    Destructor
    884 
    885    PARAMETERS
    886    None
    887 
    888    RETURN VALUE
    889    None.
    890    ========================================================================== */
    891 omx_vdec::~omx_vdec()
    892 {
    893     m_pmem_info = NULL;
    894     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
    895     if (msg_thread_created) {
    896         DEBUG_PRINT_HIGH("Signalling close to OMX Msg Thread");
    897         message_thread_stop = true;
    898         post_message(this, OMX_COMPONENT_CLOSE_MSG);
    899         DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    900         pthread_join(msg_thread_id,NULL);
    901     }
    902     close(m_pipe_in);
    903     close(m_pipe_out);
    904     m_pipe_in = -1;
    905     m_pipe_out = -1;
    906     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    907     if(eventfd_write(m_poll_efd, 1)) {
    908          DEBUG_PRINT_ERROR("eventfd_write failed for fd: %d, errno = %d, force stop async_thread", m_poll_efd, errno);
    909          async_thread_force_stop = true;
    910     }
    911 
    912     if (async_thread_created)
    913         pthread_join(async_thread_id,NULL);
    914     unsubscribe_to_events(drv_ctx.video_driver_fd);
    915     close(m_poll_efd);
    916     close(drv_ctx.video_driver_fd);
    917     pthread_mutex_destroy(&m_lock);
    918     pthread_mutex_destroy(&c_lock);
    919     pthread_mutex_destroy(&buf_lock);
    920     sem_destroy(&m_cmd_lock);
    921     if (perf_flag) {
    922         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
    923         dec_time.end();
    924     }
    925     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
    926     m_perf_control.send_hint_to_mpctl(false);
    927 }
    928 
    929 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
    930 {
    931     struct v4l2_requestbuffers bufreq;
    932     int rc = 0;
    933     if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
    934         bufreq.memory = V4L2_MEMORY_USERPTR;
    935         bufreq.count = 0;
    936         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    937         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    938     } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
    939         bufreq.memory = V4L2_MEMORY_USERPTR;
    940         bufreq.count = 0;
    941         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    942         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    943     }
    944     return rc;
    945 }
    946 
    947 OMX_ERRORTYPE omx_vdec::set_dpb(bool is_split_mode, int dpb_color_format)
    948 {
    949     int rc = 0;
    950     struct v4l2_ext_control ctrl[2];
    951     struct v4l2_ext_controls controls;
    952 
    953     DEBUG_PRINT_HIGH("DPB mode: %s DPB color format: %s OPB color format: %s",
    954          is_split_mode ? "split" : "combined",
    955          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC ? "nv12_ubwc":
    956          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC ? "nv12_10bit_ubwc":
    957          dpb_color_format == V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE ? "same as opb":
    958          "unknown",
    959          capture_capability == V4L2_PIX_FMT_NV12 ? "nv12":
    960          capture_capability == V4L2_PIX_FMT_NV12_UBWC ? "nv12_ubwc":
    961          "unknown");
    962 
    963     ctrl[0].id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
    964     if (is_split_mode) {
    965         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
    966     } else {
    967         ctrl[0].value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_PRIMARY;
    968     }
    969 
    970     ctrl[1].id = V4L2_CID_MPEG_VIDC_VIDEO_DPB_COLOR_FORMAT;
    971     ctrl[1].value = dpb_color_format;
    972 
    973     controls.count = 2;
    974     controls.ctrl_class = V4L2_CTRL_CLASS_MPEG;
    975     controls.controls = ctrl;
    976 
    977     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_EXT_CTRLS, &controls);
    978     if (rc) {
    979         DEBUG_PRINT_ERROR("Failed to set ext ctrls for opb_dpb: %d\n", rc);
    980         return OMX_ErrorUnsupportedSetting;
    981     }
    982     return OMX_ErrorNone;
    983 }
    984 
    985 
    986 OMX_ERRORTYPE omx_vdec::decide_dpb_buffer_mode(bool force_split_mode)
    987 {
    988     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    989 
    990     bool cpu_access = capture_capability != V4L2_PIX_FMT_NV12_UBWC;
    991 
    992     bool is_res_above_1080p = (drv_ctx.video_resolution.frame_width > 1920 &&
    993             drv_ctx.video_resolution.frame_height > 1088) ||
    994             (drv_ctx.video_resolution.frame_height > 1088 &&
    995              drv_ctx.video_resolution.frame_width > 1920);
    996 
    997     if (cpu_access) {
    998         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
    999             if ((m_force_compressed_for_dpb || is_res_above_1080p) &&
   1000                 !force_split_mode) {
   1001                 //split DPB-OPB
   1002                 //DPB -> UBWC , OPB -> Linear
   1003                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1004             } else if (force_split_mode) {
   1005                         //DPB -> Linear, OPB -> Linear
   1006                         eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1007             } else {
   1008                         //DPB-OPB combined linear
   1009                         eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1010            }
   1011         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1012             //split DPB-OPB
   1013             //DPB -> UBWC, OPB -> Linear
   1014             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1015         }
   1016     } else { //no cpu access
   1017         if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_8) {
   1018             if (force_split_mode) {
   1019                 //split DPB-OPB
   1020                 //DPB -> UBWC, OPB -> UBWC
   1021                 eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_UBWC);
   1022             } else {
   1023                 //DPB-OPB combined UBWC
   1024                 eRet = set_dpb(false, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_NONE);
   1025             }
   1026         } else if (dpb_bit_depth == MSM_VIDC_BIT_DEPTH_10) {
   1027             //split DPB-OPB
   1028             //DPB -> UBWC, OPB -> UBWC
   1029             eRet = set_dpb(true, V4L2_MPEG_VIDC_VIDEO_DPB_COLOR_FMT_TP10_UBWC);
   1030         }
   1031     }
   1032     if (eRet) {
   1033         DEBUG_PRINT_HIGH("Failed to set DPB buffer mode: %d", eRet);
   1034     }
   1035     return eRet;
   1036 }
   1037 
   1038 int omx_vdec::enable_downscalar()
   1039 {
   1040     int rc = 0;
   1041     struct v4l2_control control;
   1042     struct v4l2_format fmt;
   1043 
   1044     if (is_down_scalar_enabled) {
   1045         DEBUG_PRINT_LOW("%s: already enabled", __func__);
   1046         return 0;
   1047     }
   1048 
   1049     DEBUG_PRINT_LOW("omx_vdec::enable_downscalar");
   1050     rc = decide_dpb_buffer_mode(true);
   1051     if (rc) {
   1052         DEBUG_PRINT_ERROR("%s: decide_dpb_buffer_mode Failed ", __func__);
   1053         return rc;
   1054     }
   1055     is_down_scalar_enabled = true;
   1056 
   1057     memset(&control, 0x0, sizeof(struct v4l2_control));
   1058     control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
   1059     control.value = 1;
   1060     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1061     if (rc) {
   1062         DEBUG_PRINT_ERROR("%s: Failed to set VIDEO_KEEP_ASPECT_RATIO", __func__);
   1063         return rc;
   1064     }
   1065 
   1066     return 0;
   1067 }
   1068 
   1069 int omx_vdec::disable_downscalar()
   1070 {
   1071     int rc = 0;
   1072     struct v4l2_control control;
   1073 
   1074     if (!is_down_scalar_enabled) {
   1075         DEBUG_PRINT_LOW("omx_vdec::disable_downscalar: already disabled");
   1076         return 0;
   1077     }
   1078 
   1079     rc = decide_dpb_buffer_mode(false);
   1080     if (rc < 0) {
   1081         DEBUG_PRINT_ERROR("%s:decide_dpb_buffer_mode failed\n", __func__);
   1082         return rc;
   1083     }
   1084     is_down_scalar_enabled = false;
   1085 
   1086     return rc;
   1087 }
   1088 
   1089 int omx_vdec::decide_downscalar()
   1090 {
   1091     int rc = 0;
   1092     struct v4l2_format fmt;
   1093     enum color_fmts color_format;
   1094 
   1095     if  (!m_downscalar_width || !m_downscalar_height) {
   1096         DEBUG_PRINT_LOW("%s: downscalar not supported", __func__);
   1097         return 0;
   1098     }
   1099 
   1100     if (m_force_down_scalar) {
   1101         DEBUG_PRINT_LOW("%s: m_force_down_scalar %d ", __func__, m_force_down_scalar);
   1102         return 0;
   1103     }
   1104 
   1105     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1106     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1107     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1108     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   1109     if (rc < 0) {
   1110        DEBUG_PRINT_ERROR("%s: Failed to get format on capture mplane", __func__);
   1111        return rc;
   1112     }
   1113 
   1114     DEBUG_PRINT_HIGH("%s: driver wxh = %dx%d, downscalar wxh = %dx%d", __func__,
   1115         fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height, m_downscalar_width, m_downscalar_height);
   1116 
   1117     if (fmt.fmt.pix_mp.width * fmt.fmt.pix_mp.height > m_downscalar_width * m_downscalar_height) {
   1118         rc = enable_downscalar();
   1119         if (rc < 0) {
   1120             DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   1121             return rc;
   1122         }
   1123 
   1124         OMX_U32 width = m_downscalar_width > fmt.fmt.pix_mp.width ?
   1125                             fmt.fmt.pix_mp.width : m_downscalar_width;
   1126         OMX_U32 height = m_downscalar_height > fmt.fmt.pix_mp.height ?
   1127                             fmt.fmt.pix_mp.height : m_downscalar_height;
   1128         switch (capture_capability) {
   1129             case V4L2_PIX_FMT_NV12:
   1130                 color_format = COLOR_FMT_NV12;
   1131                 break;
   1132             case V4L2_PIX_FMT_NV12_UBWC:
   1133                 color_format = COLOR_FMT_NV12_UBWC;
   1134                 break;
   1135             case V4L2_PIX_FMT_NV12_TP10_UBWC:
   1136                 color_format = COLOR_FMT_NV12_BPP10_UBWC;
   1137                 break;
   1138             default:
   1139                 DEBUG_PRINT_ERROR("Color format not recognized\n");
   1140                 rc = OMX_ErrorUndefined;
   1141                 return rc;
   1142         }
   1143 
   1144         rc = update_resolution(width, height,
   1145                 VENUS_Y_STRIDE(color_format, width), VENUS_Y_SCANLINES(color_format, height));
   1146         if (rc < 0) {
   1147             DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed \n", __func__, width, height);
   1148             return rc;
   1149         }
   1150     } else {
   1151 
   1152         rc = disable_downscalar();
   1153         if (rc < 0) {
   1154             DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   1155             return rc;
   1156         }
   1157 
   1158         rc = update_resolution(fmt.fmt.pix_mp.width, fmt.fmt.pix_mp.height,
   1159                 fmt.fmt.pix_mp.plane_fmt[0].bytesperline, fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   1160         if (rc < 0) {
   1161             DEBUG_PRINT_ERROR("%s: update_resolution WxH %dx%d failed\n", __func__, fmt.fmt.pix_mp.width,
   1162                 fmt.fmt.pix_mp.height);
   1163             return rc;
   1164         }
   1165     }
   1166 
   1167     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1168     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1169     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1170     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1171     fmt.fmt.pix_mp.pixelformat = capture_capability;
   1172     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1173     if (rc) {
   1174         DEBUG_PRINT_ERROR("%s: Failed set format on capture mplane", __func__);
   1175         return rc;
   1176     }
   1177 
   1178     rc = get_buffer_req(&drv_ctx.op_buf);
   1179     if (rc) {
   1180         DEBUG_PRINT_ERROR("%s: Failed to get output buffer requirements", __func__);
   1181         return rc;
   1182     }
   1183 
   1184     return rc;
   1185 }
   1186 
   1187 /* ======================================================================
   1188    FUNCTION
   1189    omx_vdec::OMXCntrlProcessMsgCb
   1190 
   1191    DESCRIPTION
   1192    IL Client callbacks are generated through this routine. The decoder
   1193    provides the thread context for this routine.
   1194 
   1195    PARAMETERS
   1196    ctxt -- Context information related to the self.
   1197    id   -- Event identifier. This could be any of the following:
   1198    1. Command completion event
   1199    2. Buffer done callback event
   1200    3. Frame done callback event
   1201 
   1202    RETURN VALUE
   1203    None.
   1204 
   1205    ========================================================================== */
   1206 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
   1207 {
   1208     unsigned long p1; // Parameter - 1
   1209     unsigned long p2; // Parameter - 2
   1210     unsigned long ident;
   1211     unsigned qsize=0; // qsize
   1212     omx_vdec *pThis = (omx_vdec *) ctxt;
   1213 
   1214     if (!pThis) {
   1215         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
   1216                 __func__);
   1217         return;
   1218     }
   1219 
   1220     // Protect the shared queue data structure
   1221     do {
   1222         /*Read the message id's from the queue*/
   1223         pthread_mutex_lock(&pThis->m_lock);
   1224         qsize = pThis->m_cmd_q.m_size;
   1225         if (qsize) {
   1226             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
   1227         }
   1228 
   1229         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1230             qsize = pThis->m_ftb_q.m_size;
   1231             if (qsize) {
   1232                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
   1233             }
   1234         }
   1235 
   1236         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
   1237             qsize = pThis->m_etb_q.m_size;
   1238             if (qsize) {
   1239                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
   1240             }
   1241         }
   1242         pthread_mutex_unlock(&pThis->m_lock);
   1243 
   1244         /*process message if we have one*/
   1245         if (qsize > 0) {
   1246             id = ident;
   1247             switch (id) {
   1248                 case OMX_COMPONENT_GENERATE_EVENT:
   1249                     if (pThis->m_cb.EventHandler) {
   1250                         switch (p1) {
   1251                             case OMX_CommandStateSet:
   1252                                 pThis->m_state = (OMX_STATETYPE) p2;
   1253                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
   1254                                         pThis->m_state);
   1255                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1256                                         OMX_EventCmdComplete, p1, p2, NULL);
   1257                                 break;
   1258 
   1259                             case OMX_EventError:
   1260                                 if (p2 == OMX_StateInvalid) {
   1261                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
   1262                                     pThis->m_state = (OMX_STATETYPE) p2;
   1263                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1264                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
   1265                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
   1266                                     pThis->omx_report_error();
   1267                                 } else {
   1268                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1269                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
   1270                                 }
   1271                                 break;
   1272 
   1273                             case OMX_CommandPortDisable:
   1274                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
   1275                                 if (BITMASK_PRESENT(&pThis->m_flags,
   1276                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1277                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1278                                     break;
   1279                                 }
   1280                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
   1281                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1282                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   1283                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
   1284                                         DEBUG_PRINT_HIGH("Failed to release output buffers");
   1285                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
   1286                                     pThis->in_reconfig = false;
   1287                                     if (eRet !=  OMX_ErrorNone) {
   1288                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
   1289                                         pThis->omx_report_error();
   1290                                         break;
   1291                                     }
   1292                                 }
   1293                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1294                                         OMX_EventCmdComplete, p1, p2, NULL );
   1295                                 break;
   1296                             case OMX_CommandPortEnable:
   1297                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
   1298                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
   1299                                         OMX_EventCmdComplete, p1, p2, NULL );
   1300                                 break;
   1301 
   1302                             default:
   1303                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1304                                         OMX_EventCmdComplete, p1, p2, NULL );
   1305                                 break;
   1306 
   1307                         }
   1308                     } else {
   1309                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1310                     }
   1311                     break;
   1312                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
   1313                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   1314                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1315                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
   1316                         pThis->omx_report_error ();
   1317                     }
   1318                     break;
   1319                 case OMX_COMPONENT_GENERATE_ETB: {
   1320                         OMX_ERRORTYPE iret;
   1321                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
   1322                         if (iret == OMX_ErrorInsufficientResources) {
   1323                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
   1324                             pThis->omx_report_hw_overload ();
   1325                         } else if (iret != OMX_ErrorNone) {
   1326                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
   1327                             pThis->omx_report_error ();
   1328                         }
   1329                     }
   1330                     break;
   1331 
   1332                 case OMX_COMPONENT_GENERATE_FTB:
   1333                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
   1334                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
   1335                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
   1336                         pThis->omx_report_error ();
   1337                     }
   1338                     break;
   1339 
   1340                 case OMX_COMPONENT_GENERATE_COMMAND:
   1341                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
   1342                             (OMX_U32)p2,(OMX_PTR)NULL);
   1343                     break;
   1344 
   1345                 case OMX_COMPONENT_GENERATE_EBD:
   1346 
   1347                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
   1348                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
   1349                         pThis->omx_report_error ();
   1350                     } else {
   1351                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
   1352                             pThis->time_stamp_dts.remove_time_stamp(
   1353                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
   1354                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1355                                     ?true:false);
   1356                         }
   1357 
   1358                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1359                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
   1360                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
   1361                             pThis->omx_report_error ();
   1362                         }
   1363                     }
   1364                     break;
   1365                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
   1366                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
   1367                                             if (p1) {
   1368                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
   1369                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1370                                                         ?true:false);
   1371                                                 free(timestamp);
   1372                                             }
   1373                                         }
   1374                                         break;
   1375                 case OMX_COMPONENT_GENERATE_FBD:
   1376                                         if (p2 != VDEC_S_SUCCESS) {
   1377                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
   1378                                             pThis->omx_report_error ();
   1379                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1380                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
   1381                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
   1382                                             pThis->omx_report_error ();
   1383                                         }
   1384                                         break;
   1385 
   1386                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1387                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
   1388                                         if (!pThis->input_flush_progress) {
   1389                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1390                                         } else {
   1391                                             pThis->execute_input_flush();
   1392                                             if (pThis->m_cb.EventHandler) {
   1393                                                 if (p2 != VDEC_S_SUCCESS) {
   1394                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1395                                                     pThis->omx_report_error ();
   1396                                                 } else {
   1397                                                     /*Check if we need generate event for Flush done*/
   1398                                                     pThis->notify_flush_done(ctxt);
   1399 
   1400                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1401                                                                 OMX_COMPONENT_IDLE_PENDING)) {
   1402                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1403                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
   1404                                                             pThis->omx_report_error ();
   1405                                                         } else {
   1406                                                             pThis->streaming[OUTPUT_PORT] = false;
   1407                                                         }
   1408                                                         if (!pThis->output_flush_progress) {
   1409                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
   1410                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1411                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1412                                                         }
   1413                                                     }
   1414                                                 }
   1415                                             } else {
   1416                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1417                                             }
   1418                                         }
   1419                                         break;
   1420 
   1421                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1422                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
   1423                                         if (!pThis->output_flush_progress) {
   1424                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1425                                         } else {
   1426                                             pThis->execute_output_flush();
   1427                                             if (pThis->m_cb.EventHandler) {
   1428                                                 if (p2 != VDEC_S_SUCCESS) {
   1429                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1430                                                     pThis->omx_report_error ();
   1431                                                 } else {
   1432                                                     /*Check if we need generate event for Flush done*/
   1433                                                     pThis->notify_flush_done(ctxt);
   1434 
   1435                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1436                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1437                                                         DEBUG_PRINT_LOW("Internal flush complete");
   1438                                                         BITMASK_CLEAR (&pThis->m_flags,
   1439                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1440                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1441                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1442                                                             pThis->post_event(OMX_CommandPortDisable,
   1443                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1444                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1445                                                             BITMASK_CLEAR (&pThis->m_flags,
   1446                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1447                                                             BITMASK_CLEAR (&pThis->m_flags,
   1448                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1449 
   1450                                                         }
   1451                                                     }
   1452 
   1453                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1454                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1455                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
   1456                                                             pThis->omx_report_error ();
   1457                                                             break;
   1458                                                         }
   1459                                                         pThis->streaming[CAPTURE_PORT] = false;
   1460                                                         if (!pThis->input_flush_progress) {
   1461                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
   1462                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1463                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1464                                                         }
   1465                                                     }
   1466                                                 }
   1467                                             } else {
   1468                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1469                                             }
   1470                                         }
   1471                                         break;
   1472 
   1473                 case OMX_COMPONENT_GENERATE_START_DONE:
   1474                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1475 
   1476                                         if (pThis->m_cb.EventHandler) {
   1477                                             if (p2 != VDEC_S_SUCCESS) {
   1478                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
   1479                                                 pThis->omx_report_error ();
   1480                                             } else {
   1481                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
   1482                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1483                                                     DEBUG_PRINT_LOW("Move to executing");
   1484                                                     // Send the callback now
   1485                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1486                                                     pThis->m_state = OMX_StateExecuting;
   1487                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1488                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1489                                                             OMX_StateExecuting, NULL);
   1490                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1491                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1492                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1493                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1494                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
   1495                                                         pThis->omx_report_error ();
   1496                                                     }
   1497                                                 }
   1498                                             }
   1499                                         } else {
   1500                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
   1501                                         }
   1502                                         break;
   1503 
   1504                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1505                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1506                                         if (pThis->m_cb.EventHandler) {
   1507                                             if (p2 != VDEC_S_SUCCESS) {
   1508                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1509                                                 pThis->omx_report_error ();
   1510                                             } else {
   1511                                                 pThis->complete_pending_buffer_done_cbs();
   1512                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1513                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1514                                                     //Send the callback now
   1515                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1516                                                     pThis->m_state = OMX_StatePause;
   1517                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1518                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1519                                                             OMX_StatePause, NULL);
   1520                                                 }
   1521                                             }
   1522                                         } else {
   1523                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1524                                         }
   1525 
   1526                                         break;
   1527 
   1528                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1529                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1530                                         if (pThis->m_cb.EventHandler) {
   1531                                             if (p2 != VDEC_S_SUCCESS) {
   1532                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1533                                                 pThis->omx_report_error ();
   1534                                             } else {
   1535                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1536                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
   1537                                                     // Send the callback now
   1538                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1539                                                     pThis->m_state = OMX_StateExecuting;
   1540                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1541                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1542                                                             OMX_StateExecuting,NULL);
   1543                                                 }
   1544                                             }
   1545                                         } else {
   1546                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1547                                         }
   1548 
   1549                                         break;
   1550 
   1551                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1552                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1553                                         if (pThis->m_cb.EventHandler) {
   1554                                             if (p2 != VDEC_S_SUCCESS) {
   1555                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1556                                                 pThis->omx_report_error ();
   1557                                             } else {
   1558                                                 pThis->complete_pending_buffer_done_cbs();
   1559                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1560                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1561                                                     // Send the callback now
   1562                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1563                                                     pThis->m_state = OMX_StateIdle;
   1564                                                     DEBUG_PRINT_LOW("Move to Idle State");
   1565                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1566                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1567                                                             OMX_StateIdle,NULL);
   1568                                                 }
   1569                                             }
   1570                                         } else {
   1571                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1572                                         }
   1573 
   1574                                         break;
   1575 
   1576                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1577                                         if (p2 == OMX_IndexParamPortDefinition) {
   1578                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
   1579                                             pThis->in_reconfig = true;
   1580                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
   1581                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
   1582 
   1583                                             /* Check if resolution is changed in smooth streaming mode */
   1584                                             if (pThis->m_smoothstreaming_mode &&
   1585                                                 (pThis->framesize.nWidth !=
   1586                                                     pThis->drv_ctx.video_resolution.frame_width) ||
   1587                                                 (pThis->framesize.nHeight !=
   1588                                                     pThis->drv_ctx.video_resolution.frame_height)) {
   1589 
   1590                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
   1591                                                         pThis->framesize.nWidth,
   1592                                                         pThis->framesize.nHeight,
   1593                                                         pThis->drv_ctx.video_resolution.frame_width,
   1594                                                         pThis->drv_ctx.video_resolution.frame_height);
   1595 
   1596                                                 /* Update new resolution */
   1597                                                 pThis->framesize.nWidth =
   1598                                                        pThis->drv_ctx.video_resolution.frame_width;
   1599                                                 pThis->framesize.nHeight =
   1600                                                        pThis->drv_ctx.video_resolution.frame_height;
   1601 
   1602                                                 /* Update C2D with new resolution */
   1603                                                 if (!pThis->client_buffers.update_buffer_req()) {
   1604                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
   1605                                                 }
   1606                                             }
   1607 
   1608                                             /* Update new crop information */
   1609                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
   1610                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
   1611                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
   1612                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
   1613 
   1614                                             /* Validate the new crop information */
   1615                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
   1616                                                 pThis->drv_ctx.video_resolution.frame_width) {
   1617 
   1618                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
   1619                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
   1620                                                         pThis->drv_ctx.video_resolution.frame_width);
   1621                                                 pThis->rectangle.nLeft = 0;
   1622 
   1623                                                 if (pThis->rectangle.nWidth >
   1624                                                     pThis->drv_ctx.video_resolution.frame_width) {
   1625 
   1626                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
   1627                                                             pThis->rectangle.nWidth,
   1628                                                             pThis->drv_ctx.video_resolution.frame_width);
   1629                                                     pThis->rectangle.nWidth =
   1630                                                         pThis->drv_ctx.video_resolution.frame_width;
   1631                                                 }
   1632                                             }
   1633                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
   1634                                                 pThis->drv_ctx.video_resolution.frame_height) {
   1635 
   1636                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
   1637                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
   1638                                                     pThis->drv_ctx.video_resolution.frame_height);
   1639                                                 pThis->rectangle.nTop = 0;
   1640 
   1641                                                 if (pThis->rectangle.nHeight >
   1642                                                     pThis->drv_ctx.video_resolution.frame_height) {
   1643 
   1644                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
   1645                                                         pThis->rectangle.nHeight,
   1646                                                         pThis->drv_ctx.video_resolution.frame_height);
   1647                                                     pThis->rectangle.nHeight =
   1648                                                         pThis->drv_ctx.video_resolution.frame_height;
   1649                                                 }
   1650                                             }
   1651                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
   1652                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
   1653                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
   1654                                         } else if (p2 == OMX_QTIIndexConfigDescribeColorAspects) {
   1655                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_QTIIndexConfigDescribeColorAspects");
   1656                                         } else {
   1657                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
   1658                                             break;
   1659                                         }
   1660                                         if (pThis->m_debug.outfile) {
   1661                                             fclose(pThis->m_debug.outfile);
   1662                                             pThis->m_debug.outfile = NULL;
   1663                                         }
   1664                                         if (pThis->m_debug.out_ymeta_file) {
   1665                                             fclose(pThis->m_debug.out_ymeta_file);
   1666                                             pThis->m_debug.out_ymeta_file = NULL;
   1667                                         }
   1668                                         if (pThis->m_debug.out_uvmeta_file) {
   1669                                             fclose(pThis->m_debug.out_uvmeta_file);
   1670                                             pThis->m_debug.out_uvmeta_file = NULL;
   1671                                         }
   1672 
   1673                                         if (pThis->secure_mode && pThis->m_cb.EventHandler && pThis->in_reconfig) {
   1674                                             pThis->prefetchNewBuffers();
   1675                                         }
   1676 
   1677                                         if (pThis->m_cb.EventHandler) {
   1678                                             uint32_t frame_data[2];
   1679                                             frame_data[0] = (p2 == OMX_IndexParamPortDefinition) ?
   1680                                                 pThis->m_reconfig_height : pThis->rectangle.nHeight;
   1681                                             frame_data[1] = (p2 == OMX_IndexParamPortDefinition) ?
   1682                                                 pThis->m_reconfig_width : pThis->rectangle.nWidth;
   1683                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1684                                                     OMX_EventPortSettingsChanged, p1, p2, (void*) frame_data );
   1685                                         } else {
   1686                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1687                                         }
   1688                                         break;
   1689 
   1690                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1691                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1692                                         if (pThis->m_cb.EventHandler) {
   1693                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1694                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1695                                         } else {
   1696                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1697                                         }
   1698                                         pThis->prev_ts = LLONG_MAX;
   1699                                         pThis->rst_prev_ts = true;
   1700                                         break;
   1701 
   1702                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1703                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1704                                         pThis->omx_report_error();
   1705                                         break;
   1706 
   1707                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1708                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
   1709                                         pThis->omx_report_unsupported_setting();
   1710                                         break;
   1711 
   1712                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
   1713                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
   1714                                         pThis->omx_report_hw_overload();
   1715                                         break;
   1716 
   1717                 default:
   1718                                         break;
   1719             }
   1720         }
   1721         pthread_mutex_lock(&pThis->m_lock);
   1722         qsize = pThis->m_cmd_q.m_size;
   1723         if (pThis->m_state != OMX_StatePause)
   1724             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1725         pthread_mutex_unlock(&pThis->m_lock);
   1726     } while (qsize>0);
   1727 
   1728 }
   1729 
   1730 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1731 {
   1732     int format_changed = 0;
   1733     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
   1734             (width != (int)drv_ctx.video_resolution.frame_width)) {
   1735         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
   1736                 width, drv_ctx.video_resolution.frame_width,
   1737                 height,drv_ctx.video_resolution.frame_height);
   1738         format_changed = 1;
   1739     }
   1740     drv_ctx.video_resolution.frame_height = height;
   1741     drv_ctx.video_resolution.frame_width = width;
   1742     drv_ctx.video_resolution.scan_lines = scan_lines;
   1743     drv_ctx.video_resolution.stride = stride;
   1744     if(!is_down_scalar_enabled) {
   1745         rectangle.nLeft = 0;
   1746         rectangle.nTop = 0;
   1747         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   1748         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   1749     }
   1750     return format_changed;
   1751 }
   1752 
   1753 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1754 {
   1755     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1756                 OMX_MAX_STRINGNAME_SIZE) &&
   1757             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1758         m_decoder_capability.max_width = 1280;
   1759         m_decoder_capability.max_height = 720;
   1760         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1761     }
   1762 
   1763     if ((drv_ctx.video_resolution.frame_width *
   1764                 drv_ctx.video_resolution.frame_height >
   1765                 m_decoder_capability.max_width *
   1766                 m_decoder_capability.max_height) ||
   1767             (drv_ctx.video_resolution.frame_width*
   1768              drv_ctx.video_resolution.frame_height <
   1769              m_decoder_capability.min_width *
   1770              m_decoder_capability.min_height)) {
   1771         DEBUG_PRINT_ERROR(
   1772                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1773                 drv_ctx.video_resolution.frame_width,
   1774                 drv_ctx.video_resolution.frame_height,
   1775                 m_decoder_capability.min_width,
   1776                 m_decoder_capability.min_height,
   1777                 m_decoder_capability.max_width,
   1778                 m_decoder_capability.max_height);
   1779         return OMX_ErrorUnsupportedSetting;
   1780     }
   1781     DEBUG_PRINT_HIGH("video session supported");
   1782     return OMX_ErrorNone;
   1783 }
   1784 
   1785 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
   1786 {
   1787     if (m_debug.in_buffer_log && !m_debug.infile) {
   1788         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   1789            snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.m4v",
   1790                    m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1791         } else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   1792                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc,
   1793                         drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1794         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   1795                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.263",
   1796                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1797         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
   1798                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   1799                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.264",
   1800                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1801         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   1802                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.265",
   1803                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1804         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   1805                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   1806                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1807         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
   1808                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.vc1",
   1809                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1810         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   1811                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   1812                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1813         } else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1814                 snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.ivf",
   1815                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1816         } else {
   1817                snprintf(m_debug.infile_name, OMX_MAX_STRINGNAME_SIZE, "%s/input_dec_%d_%d_%p.divx",
   1818                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1819         }
   1820         m_debug.infile = fopen (m_debug.infile_name, "ab");
   1821         if (!m_debug.infile) {
   1822             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   1823             m_debug.infile_name[0] = '\0';
   1824             return -1;
   1825         }
   1826         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   1827                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1828             struct ivf_file_header {
   1829                 OMX_U8 signature[4]; //='DKIF';
   1830                 OMX_U8 version         ; //= 0;
   1831                 OMX_U8 headersize      ; //= 32;
   1832                 OMX_U32 FourCC;
   1833                 OMX_U8 width;
   1834                 OMX_U8 height;
   1835                 OMX_U32 rate;
   1836                 OMX_U32 scale;
   1837                 OMX_U32 length;
   1838                 OMX_U8 unused[4];
   1839             } file_header;
   1840 
   1841             memset((void *)&file_header,0,sizeof(file_header));
   1842             file_header.signature[0] = 'D';
   1843             file_header.signature[1] = 'K';
   1844             file_header.signature[2] = 'I';
   1845             file_header.signature[3] = 'F';
   1846             file_header.version = 0;
   1847             file_header.headersize = 32;
   1848             switch (drv_ctx.decoder_format) {
   1849                 case VDEC_CODECTYPE_VP8:
   1850                     file_header.FourCC = 0x30385056;
   1851                     break;
   1852                 case VDEC_CODECTYPE_VP9:
   1853                     file_header.FourCC = 0x30395056;
   1854                     break;
   1855                 default:
   1856                     DEBUG_PRINT_ERROR("unsupported format for VP8/VP9");
   1857                     break;
   1858             }
   1859             fwrite((const char *)&file_header,
   1860                     sizeof(file_header),1,m_debug.infile);
   1861          }
   1862     }
   1863     if (m_debug.infile && buffer_addr && buffer_len) {
   1864         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   1865                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   1866             struct vpx_ivf_frame_header {
   1867                 OMX_U32 framesize;
   1868                 OMX_U32 timestamp_lo;
   1869                 OMX_U32 timestamp_hi;
   1870             } vpx_frame_header;
   1871             vpx_frame_header.framesize = buffer_len;
   1872             /* Currently FW doesn't use timestamp values */
   1873             vpx_frame_header.timestamp_lo = 0;
   1874             vpx_frame_header.timestamp_hi = 0;
   1875             fwrite((const char *)&vpx_frame_header,
   1876                     sizeof(vpx_frame_header),1,m_debug.infile);
   1877         }
   1878         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
   1879     }
   1880     return 0;
   1881 }
   1882 
   1883 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
   1884     int buf_index = 0;
   1885     char *temp = NULL;
   1886 
   1887     if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) {
   1888         snprintf(m_debug.outfile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.yuv",
   1889                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1890         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
   1891         if (!m_debug.outfile) {
   1892             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
   1893             m_debug.outfile_name[0] = '\0';
   1894             return -1;
   1895         }
   1896     }
   1897 
   1898     if (m_debug.out_meta_buffer_log && !m_debug.out_ymeta_file && !m_debug.out_uvmeta_file
   1899         && buffer->nFilledLen) {
   1900         snprintf(m_debug.out_ymetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.ymeta",
   1901                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1902         snprintf(m_debug.out_uvmetafile_name, OMX_MAX_STRINGNAME_SIZE, "%s/output_%d_%d_%p.uvmeta",
   1903                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1904         m_debug.out_ymeta_file = fopen (m_debug.out_ymetafile_name, "ab");
   1905         m_debug.out_uvmeta_file = fopen (m_debug.out_uvmetafile_name, "ab");
   1906         if (!m_debug.out_ymeta_file || !m_debug.out_uvmeta_file) {
   1907             DEBUG_PRINT_HIGH("Failed to open output y/uv meta file: %s for logging", m_debug.log_loc);
   1908             m_debug.out_ymetafile_name[0] = '\0';
   1909             m_debug.out_uvmetafile_name[0] = '\0';
   1910             return -1;
   1911         }
   1912     }
   1913 
   1914     if ((!m_debug.outfile && !m_debug.out_ymeta_file) || !buffer || !buffer->nFilledLen)
   1915         return 0;
   1916 
   1917     buf_index = buffer - m_out_mem_ptr;
   1918     temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   1919 
   1920     if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   1921         DEBUG_PRINT_HIGH("Logging UBWC yuv width/height(%u/%u)",
   1922             drv_ctx.video_resolution.frame_width,
   1923             drv_ctx.video_resolution.frame_height);
   1924 
   1925         if (m_debug.outfile)
   1926             fwrite(temp, buffer->nFilledLen, 1, m_debug.outfile);
   1927 
   1928         if (m_debug.out_ymeta_file && m_debug.out_uvmeta_file) {
   1929             unsigned int width = 0, height = 0;
   1930             unsigned int y_plane, y_meta_plane;
   1931             int y_stride = 0, y_sclines = 0;
   1932             int y_meta_stride = 0, y_meta_scanlines = 0, uv_meta_stride = 0, uv_meta_scanlines = 0;
   1933             int color_fmt = COLOR_FMT_NV12_UBWC;
   1934             int i;
   1935             int bytes_written = 0;
   1936 
   1937             width = drv_ctx.video_resolution.frame_width;
   1938             height = drv_ctx.video_resolution.frame_height;
   1939             y_meta_stride = VENUS_Y_META_STRIDE(color_fmt, width);
   1940             y_meta_scanlines = VENUS_Y_META_SCANLINES(color_fmt, height);
   1941             y_stride = VENUS_Y_STRIDE(color_fmt, width);
   1942             y_sclines = VENUS_Y_SCANLINES(color_fmt, height);
   1943             uv_meta_stride = VENUS_UV_META_STRIDE(color_fmt, width);
   1944             uv_meta_scanlines = VENUS_UV_META_SCANLINES(color_fmt, height);
   1945 
   1946             y_meta_plane = MSM_MEDIA_ALIGN(y_meta_stride * y_meta_scanlines, 4096);
   1947             y_plane = MSM_MEDIA_ALIGN(y_stride * y_sclines, 4096);
   1948 
   1949             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   1950             for (i = 0; i < y_meta_scanlines; i++) {
   1951                  bytes_written = fwrite(temp, y_meta_stride, 1, m_debug.out_ymeta_file);
   1952                  temp += y_meta_stride;
   1953             }
   1954 
   1955             temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + y_meta_plane + y_plane;
   1956             for(i = 0; i < uv_meta_scanlines; i++) {
   1957                 bytes_written += fwrite(temp, uv_meta_stride, 1, m_debug.out_uvmeta_file);
   1958                 temp += uv_meta_stride;
   1959             }
   1960         }
   1961     } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12 && m_debug.outfile) {
   1962         int stride = drv_ctx.video_resolution.stride;
   1963         int scanlines = drv_ctx.video_resolution.scan_lines;
   1964         if (m_smoothstreaming_mode) {
   1965             stride = drv_ctx.video_resolution.frame_width;
   1966             scanlines = drv_ctx.video_resolution.frame_height;
   1967             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
   1968             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
   1969         }
   1970         unsigned i;
   1971         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
   1972             drv_ctx.video_resolution.frame_width,
   1973             drv_ctx.video_resolution.frame_height, stride, scanlines);
   1974         int bytes_written = 0;
   1975         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   1976              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1977              temp += stride;
   1978         }
   1979         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   1980         int stride_c = stride;
   1981         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   1982             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1983             temp += stride_c;
   1984         }
   1985     }
   1986     return 0;
   1987 }
   1988 
   1989 /* ======================================================================
   1990    FUNCTION
   1991    omx_vdec::ComponentInit
   1992 
   1993    DESCRIPTION
   1994    Initialize the component.
   1995 
   1996    PARAMETERS
   1997    ctxt -- Context information related to the self.
   1998    id   -- Event identifier. This could be any of the following:
   1999    1. Command completion event
   2000    2. Buffer done callback event
   2001    3. Frame done callback event
   2002 
   2003    RETURN VALUE
   2004    None.
   2005 
   2006    ========================================================================== */
   2007 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   2008 {
   2009 
   2010     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2011     struct v4l2_fmtdesc fdesc;
   2012     struct v4l2_format fmt;
   2013     struct v4l2_requestbuffers bufreq;
   2014     struct v4l2_control control;
   2015     struct v4l2_frmsizeenum frmsize;
   2016     unsigned int   alignment = 0,buffer_size = 0;
   2017     int fds[2];
   2018     int r,ret=0;
   2019     bool codec_ambiguous = false;
   2020     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
   2021     char property_value[PROPERTY_VALUE_MAX] = {0};
   2022     FILE *soc_file = NULL;
   2023     char buffer[10];
   2024 
   2025 #ifdef _ANDROID_
   2026     char platform_name[PROPERTY_VALUE_MAX];
   2027     property_get("ro.board.platform", platform_name, "0");
   2028     if (!strncmp(platform_name, "msm8610", 7)) {
   2029         device_name = (OMX_STRING)"/dev/video/q6_dec";
   2030         is_q6_platform = true;
   2031         maxSmoothStreamingWidth = 1280;
   2032         maxSmoothStreamingHeight = 720;
   2033     }
   2034 #endif
   2035 
   2036     is_thulium_v1 = false;
   2037     soc_file = fopen("/sys/devices/soc0/soc_id", "r");
   2038     if (soc_file) {
   2039         fread(buffer, 1, 4, soc_file);
   2040         fclose(soc_file);
   2041         if (atoi(buffer) == 246) {
   2042             soc_file = fopen("/sys/devices/soc0/revision", "r");
   2043             if (soc_file) {
   2044                 fread(buffer, 1, 4, soc_file);
   2045                 fclose(soc_file);
   2046                 if (atoi(buffer) == 1) {
   2047                     is_thulium_v1 = true;
   2048                     DEBUG_PRINT_HIGH("is_thulium_v1 = TRUE");
   2049                 }
   2050             }
   2051         }
   2052     }
   2053 
   2054 #ifdef _ANDROID_
   2055     /*
   2056      * turn off frame parsing for Android by default.
   2057      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
   2058      */
   2059     arbitrary_bytes = false;
   2060     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   2061     if (atoi(property_value)) {
   2062         DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
   2063         arbitrary_bytes = true;
   2064     }
   2065 #endif
   2066 
   2067     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
   2068                 OMX_MAX_STRINGNAME_SIZE)) {
   2069         secure_mode = true;
   2070         arbitrary_bytes = false;
   2071         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   2072     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
   2073                 OMX_MAX_STRINGNAME_SIZE)) {
   2074         secure_mode = true;
   2075         arbitrary_bytes = false;
   2076         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
   2077     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
   2078                 OMX_MAX_STRINGNAME_SIZE)) {
   2079         secure_mode = true;
   2080         arbitrary_bytes = false;
   2081         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
   2082     } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
   2083                 OMX_MAX_STRINGNAME_SIZE)) {
   2084         secure_mode = true;
   2085         arbitrary_bytes = false;
   2086         role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
   2087     } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
   2088                 OMX_MAX_STRINGNAME_SIZE)) {
   2089         secure_mode = true;
   2090         arbitrary_bytes = false;
   2091         role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
   2092     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
   2093                 OMX_MAX_STRINGNAME_SIZE)) {
   2094         secure_mode = true;
   2095         arbitrary_bytes = false;
   2096         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
   2097     } else if (!strncmp(role, "OMX.qcom.video.decoder.vp9.secure",
   2098                 OMX_MAX_STRINGNAME_SIZE)) {
   2099         secure_mode = true;
   2100         arbitrary_bytes = false;
   2101         role = (OMX_STRING)"OMX.qcom.video.decoder.vp9";
   2102     }
   2103 
   2104     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   2105 
   2106     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
   2107 
   2108     if (drv_ctx.video_driver_fd < 0) {
   2109         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
   2110         return OMX_ErrorInsufficientResources;
   2111     }
   2112     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   2113     drv_ctx.frame_rate.fps_denominator = 1;
   2114     m_poll_efd = eventfd(0, 0);
   2115     if (m_poll_efd < 0) {
   2116         DEBUG_PRINT_ERROR("Failed to create event fd(%s)", strerror(errno));
   2117         return OMX_ErrorInsufficientResources;
   2118     }
   2119     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   2120     if (!ret) {
   2121         async_thread_created = true;
   2122         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   2123     }
   2124     if (ret) {
   2125         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
   2126         async_thread_created = false;
   2127         return OMX_ErrorInsufficientResources;
   2128     }
   2129 
   2130 #ifdef OUTPUT_EXTRADATA_LOG
   2131     outputExtradataFile = fopen (output_extradata_filename, "ab");
   2132 #endif
   2133 
   2134     // Copy the role information which provides the decoder kind
   2135     strlcpy(drv_ctx.kind,role,128);
   2136 
   2137     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   2138                 OMX_MAX_STRINGNAME_SIZE)) {
   2139         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   2140                 OMX_MAX_STRINGNAME_SIZE);
   2141         drv_ctx.timestamp_adjust = true;
   2142         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   2143         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   2144         output_capability=V4L2_PIX_FMT_MPEG4;
   2145         /*Initialize Start Code for MPEG4*/
   2146         codec_type_parse = CODEC_TYPE_MPEG4;
   2147         m_frame_parser.init_start_codes(codec_type_parse);
   2148     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   2149                 OMX_MAX_STRINGNAME_SIZE)) {
   2150         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   2151                 OMX_MAX_STRINGNAME_SIZE);
   2152         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   2153         output_capability = V4L2_PIX_FMT_MPEG2;
   2154         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   2155         /*Initialize Start Code for MPEG2*/
   2156         codec_type_parse = CODEC_TYPE_MPEG2;
   2157         m_frame_parser.init_start_codes(codec_type_parse);
   2158     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   2159                 OMX_MAX_STRINGNAME_SIZE)) {
   2160         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   2161         DEBUG_PRINT_LOW("H263 Decoder selected");
   2162         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   2163         eCompressionFormat = OMX_VIDEO_CodingH263;
   2164         output_capability = V4L2_PIX_FMT_H263;
   2165         codec_type_parse = CODEC_TYPE_H263;
   2166         m_frame_parser.init_start_codes(codec_type_parse);
   2167     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   2168                 OMX_MAX_STRINGNAME_SIZE)) {
   2169         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2170         DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
   2171         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   2172         output_capability = V4L2_PIX_FMT_DIVX_311;
   2173         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2174         codec_type_parse = CODEC_TYPE_DIVX;
   2175         m_frame_parser.init_start_codes(codec_type_parse);
   2176 
   2177     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   2178                 OMX_MAX_STRINGNAME_SIZE)) {
   2179         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2180         DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
   2181         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   2182         output_capability = V4L2_PIX_FMT_DIVX;
   2183         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2184         codec_type_parse = CODEC_TYPE_DIVX;
   2185         codec_ambiguous = true;
   2186         m_frame_parser.init_start_codes(codec_type_parse);
   2187 
   2188     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   2189                 OMX_MAX_STRINGNAME_SIZE)) {
   2190         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   2191         DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
   2192         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   2193         output_capability = V4L2_PIX_FMT_DIVX;
   2194         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   2195         codec_type_parse = CODEC_TYPE_DIVX;
   2196         codec_ambiguous = true;
   2197         m_frame_parser.init_start_codes(codec_type_parse);
   2198 
   2199     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   2200                 OMX_MAX_STRINGNAME_SIZE)) {
   2201         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   2202         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   2203         output_capability=V4L2_PIX_FMT_H264;
   2204         eCompressionFormat = OMX_VIDEO_CodingAVC;
   2205         codec_type_parse = CODEC_TYPE_H264;
   2206         m_frame_parser.init_start_codes(codec_type_parse);
   2207         m_frame_parser.init_nal_length(nal_length);
   2208         if (is_thulium_v1) {
   2209             arbitrary_bytes = true;
   2210             DEBUG_PRINT_HIGH("Enable arbitrary_bytes for h264");
   2211         }
   2212     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
   2213                 OMX_MAX_STRINGNAME_SIZE)) {
   2214         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   2215         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
   2216         output_capability = V4L2_PIX_FMT_H264_MVC;
   2217         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
   2218         codec_type_parse = CODEC_TYPE_H264;
   2219         m_frame_parser.init_start_codes(codec_type_parse);
   2220         m_frame_parser.init_nal_length(nal_length);
   2221     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
   2222                 OMX_MAX_STRINGNAME_SIZE)) {
   2223         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
   2224         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
   2225         output_capability = V4L2_PIX_FMT_HEVC;
   2226         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
   2227         codec_type_parse = CODEC_TYPE_HEVC;
   2228         m_frame_parser.init_start_codes(codec_type_parse);
   2229         m_frame_parser.init_nal_length(nal_length);
   2230     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   2231                 OMX_MAX_STRINGNAME_SIZE)) {
   2232         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2233         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   2234         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2235         codec_type_parse = CODEC_TYPE_VC1;
   2236         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   2237         m_frame_parser.init_start_codes(codec_type_parse);
   2238     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   2239                 OMX_MAX_STRINGNAME_SIZE)) {
   2240         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   2241         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   2242         eCompressionFormat = OMX_VIDEO_CodingWMV;
   2243         codec_type_parse = CODEC_TYPE_VC1;
   2244         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   2245         m_frame_parser.init_start_codes(codec_type_parse);
   2246     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   2247                 OMX_MAX_STRINGNAME_SIZE)) {
   2248         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   2249         drv_ctx.decoder_format = VDEC_CODECTYPE_VP8;
   2250         output_capability = V4L2_PIX_FMT_VP8;
   2251         eCompressionFormat = OMX_VIDEO_CodingVP8;
   2252         codec_type_parse = CODEC_TYPE_VP8;
   2253         arbitrary_bytes = false;
   2254     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",    \
   2255                 OMX_MAX_STRINGNAME_SIZE)) {
   2256         strlcpy((char *)m_cRole, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   2257         drv_ctx.decoder_format = VDEC_CODECTYPE_VP9;
   2258         output_capability = V4L2_PIX_FMT_VP9;
   2259         eCompressionFormat = OMX_VIDEO_CodingVP9;
   2260         codec_type_parse = CODEC_TYPE_VP9;
   2261         arbitrary_bytes = false;
   2262     } else {
   2263         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
   2264         eRet = OMX_ErrorInvalidComponentName;
   2265     }
   2266 
   2267     if (eRet == OMX_ErrorNone) {
   2268         OMX_COLOR_FORMATTYPE dest_color_format;
   2269         if (m_disable_ubwc_mode) {
   2270             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   2271         } else {
   2272             drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   2273         }
   2274         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
   2275             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2276                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   2277         else
   2278             dest_color_format = (OMX_COLOR_FORMATTYPE)
   2279                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   2280         if (!client_buffers.set_color_format(dest_color_format)) {
   2281             DEBUG_PRINT_ERROR("Setting color format failed");
   2282             eRet = OMX_ErrorInsufficientResources;
   2283         }
   2284 
   2285         dpb_bit_depth = MSM_VIDC_BIT_DEPTH_8;
   2286 
   2287         if (m_disable_ubwc_mode) {
   2288             capture_capability = V4L2_PIX_FMT_NV12;
   2289         } else {
   2290             capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   2291         }
   2292 
   2293         struct v4l2_capability cap;
   2294         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   2295         if (ret) {
   2296             DEBUG_PRINT_ERROR("Failed to query capabilities");
   2297             /*TODO: How to handle this case */
   2298         } else {
   2299             DEBUG_PRINT_LOW("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   2300                 " version = %d, capabilities = %x", cap.driver, cap.card,
   2301                 cap.bus_info, cap.version, cap.capabilities);
   2302         }
   2303         ret=0;
   2304         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2305         fdesc.index=0;
   2306         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2307             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2308                     fdesc.pixelformat, fdesc.flags);
   2309             fdesc.index++;
   2310         }
   2311         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2312         fdesc.index=0;
   2313         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   2314 
   2315             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   2316                     fdesc.pixelformat, fdesc.flags);
   2317             fdesc.index++;
   2318         }
   2319         update_resolution(320, 240, 320, 240);
   2320         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   2321         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2322         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2323         fmt.fmt.pix_mp.pixelformat = output_capability;
   2324         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2325         if (ret) {
   2326             /*TODO: How to handle this case */
   2327             DEBUG_PRINT_ERROR("Failed to set format on output port");
   2328             return OMX_ErrorInsufficientResources;
   2329         }
   2330         DEBUG_PRINT_HIGH("Set Format was successful");
   2331         if (codec_ambiguous) {
   2332             if (output_capability == V4L2_PIX_FMT_DIVX) {
   2333                 struct v4l2_control divx_ctrl;
   2334 
   2335                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   2336                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   2337                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   2338                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   2339                 } else {
   2340                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   2341                 }
   2342 
   2343                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   2344                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   2345                 if (ret) {
   2346                     DEBUG_PRINT_ERROR("Failed to set divx version");
   2347                 }
   2348             } else {
   2349                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   2350             }
   2351         }
   2352 
   2353         property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
   2354         m_conceal_color= atoi(property_value);
   2355         DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
   2356         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
   2357         control.value = m_conceal_color;
   2358         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2359         if (ret) {
   2360             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
   2361         }
   2362 
   2363         //Get the hardware capabilities
   2364         memset((void *)&frmsize,0,sizeof(frmsize));
   2365         frmsize.index = 0;
   2366         frmsize.pixel_format = output_capability;
   2367         ret = ioctl(drv_ctx.video_driver_fd,
   2368                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   2369         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   2370             DEBUG_PRINT_ERROR("Failed to get framesizes");
   2371             return OMX_ErrorHardware;
   2372         }
   2373 
   2374         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   2375             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   2376             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   2377             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   2378             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   2379         }
   2380 
   2381         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   2382         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   2383         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   2384         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   2385         fmt.fmt.pix_mp.pixelformat = capture_capability;
   2386         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   2387         if (ret) {
   2388             /*TODO: How to handle this case */
   2389             DEBUG_PRINT_ERROR("Failed to set format on capture port");
   2390         }
   2391         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
   2392         framesize.nWidth = drv_ctx.video_resolution.frame_width;
   2393         framesize.nHeight = drv_ctx.video_resolution.frame_height;
   2394 
   2395         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
   2396         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   2397         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   2398 
   2399         DEBUG_PRINT_HIGH("Set Format was successful");
   2400         if (secure_mode) {
   2401             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   2402             control.value = 1;
   2403             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
   2404             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   2405             if (ret) {
   2406                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
   2407                 return OMX_ErrorInsufficientResources;
   2408             }
   2409         }
   2410         if (output_capability == V4L2_PIX_FMT_H264_MVC) {
   2411             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
   2412             control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
   2413             ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2414             if (ret) {
   2415                 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
   2416                 return OMX_ErrorInsufficientResources;
   2417             }
   2418         }
   2419 
   2420         if (is_thulium_v1) {
   2421             eRet = enable_smoothstreaming();
   2422             if (eRet != OMX_ErrorNone) {
   2423                DEBUG_PRINT_ERROR("Failed to enable smooth streaming on driver");
   2424                return eRet;
   2425             }
   2426         }
   2427 
   2428         /*Get the Buffer requirements for input and output ports*/
   2429         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   2430         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   2431 
   2432         if (secure_mode) {
   2433             drv_ctx.op_buf.alignment = SECURE_ALIGN;
   2434             drv_ctx.ip_buf.alignment = SECURE_ALIGN;
   2435         } else {
   2436             drv_ctx.op_buf.alignment = SZ_4K;
   2437             drv_ctx.ip_buf.alignment = SZ_4K;
   2438         }
   2439 
   2440         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   2441         drv_ctx.extradata = 0;
   2442         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   2443         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   2444         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   2445         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   2446         drv_ctx.idr_only_decoding = 0;
   2447 
   2448 #ifdef _ANDROID_
   2449         property_get("vidc.dec.downscalar_width",property_value,"0");
   2450         if (atoi(property_value)) {
   2451             m_downscalar_width = atoi(property_value);
   2452         }
   2453         property_get("vidc.dec.downscalar_height",property_value,"0");
   2454         if (atoi(property_value)) {
   2455             m_downscalar_height = atoi(property_value);
   2456         }
   2457 
   2458         if (m_downscalar_width < m_decoder_capability.min_width ||
   2459             m_downscalar_height < m_decoder_capability.min_height) {
   2460             m_downscalar_width = 0;
   2461             m_downscalar_height = 0;
   2462         }
   2463 
   2464         DEBUG_PRINT_LOW("Downscaler configured WxH %dx%d\n",
   2465             m_downscalar_width, m_downscalar_height);
   2466 #endif
   2467         m_state = OMX_StateLoaded;
   2468 #ifdef DEFAULT_EXTRADATA
   2469         if ((strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
   2470                     OMX_MAX_STRINGNAME_SIZE) &&
   2471                 strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",
   2472                         OMX_MAX_STRINGNAME_SIZE)) &&
   2473                 (eRet == OMX_ErrorNone))
   2474                 enable_extradata(DEFAULT_EXTRADATA, true, true);
   2475 #endif
   2476         eRet = get_buffer_req(&drv_ctx.ip_buf);
   2477         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
   2478         get_buffer_req(&drv_ctx.op_buf);
   2479         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2480                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
   2481                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2482                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   2483                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   2484                     h264_scratch.nFilledLen = 0;
   2485                     h264_scratch.nOffset = 0;
   2486 
   2487                     if (h264_scratch.pBuffer == NULL) {
   2488                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
   2489                         return OMX_ErrorInsufficientResources;
   2490                     }
   2491         }
   2492         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2493             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2494             if (m_frame_parser.mutils == NULL) {
   2495                 m_frame_parser.mutils = new H264_Utils();
   2496                 if (m_frame_parser.mutils == NULL) {
   2497                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
   2498                     eRet = OMX_ErrorInsufficientResources;
   2499                 } else {
   2500                     m_frame_parser.mutils->initialize_frame_checking_environment();
   2501                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   2502                 }
   2503             }
   2504 
   2505             h264_parser = new h264_stream_parser();
   2506             if (!h264_parser) {
   2507                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   2508                 eRet = OMX_ErrorInsufficientResources;
   2509             }
   2510         }
   2511 
   2512         if (pipe(fds)) {
   2513             DEBUG_PRINT_ERROR("pipe creation failed");
   2514             eRet = OMX_ErrorInsufficientResources;
   2515         } else {
   2516             m_pipe_in = fds[0];
   2517             m_pipe_out = fds[1];
   2518             msg_thread_created = true;
   2519             r = pthread_create(&msg_thread_id,0,message_thread,this);
   2520 
   2521             if (r < 0) {
   2522                 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
   2523                 msg_thread_created = false;
   2524                 eRet = OMX_ErrorInsufficientResources;
   2525             }
   2526         }
   2527     }
   2528 
   2529     {
   2530         VendorExtensionStore *extStore = const_cast<VendorExtensionStore *>(&mVendorExtensionStore);
   2531         init_vendor_extensions(*extStore);
   2532         mVendorExtensionStore.dumpExtensions((const char *)role);
   2533     }
   2534 
   2535     if (eRet != OMX_ErrorNone) {
   2536         DEBUG_PRINT_ERROR("Component Init Failed");
   2537     } else {
   2538         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
   2539                 drv_ctx.video_driver_fd);
   2540     }
   2541     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   2542     return eRet;
   2543 }
   2544 
   2545 /* ======================================================================
   2546    FUNCTION
   2547    omx_vdec::GetComponentVersion
   2548 
   2549    DESCRIPTION
   2550    Returns the component version.
   2551 
   2552    PARAMETERS
   2553    TBD.
   2554 
   2555    RETURN VALUE
   2556    OMX_ErrorNone.
   2557 
   2558    ========================================================================== */
   2559 OMX_ERRORTYPE  omx_vdec::get_component_version
   2560 (
   2561  OMX_IN OMX_HANDLETYPE hComp,
   2562  OMX_OUT OMX_STRING componentName,
   2563  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   2564  OMX_OUT OMX_VERSIONTYPE* specVersion,
   2565  OMX_OUT OMX_UUIDTYPE* componentUUID
   2566  )
   2567 {
   2568     (void) hComp;
   2569     (void) componentName;
   2570     (void) componentVersion;
   2571     (void) componentUUID;
   2572     if (m_state == OMX_StateInvalid) {
   2573         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
   2574         return OMX_ErrorInvalidState;
   2575     }
   2576     /* TBD -- Return the proper version */
   2577     if (specVersion) {
   2578         specVersion->nVersion = OMX_SPEC_VERSION;
   2579     }
   2580     return OMX_ErrorNone;
   2581 }
   2582 /* ======================================================================
   2583    FUNCTION
   2584    omx_vdec::SendCommand
   2585 
   2586    DESCRIPTION
   2587    Returns zero if all the buffers released..
   2588 
   2589    PARAMETERS
   2590    None.
   2591 
   2592    RETURN VALUE
   2593    true/false
   2594 
   2595    ========================================================================== */
   2596 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   2597         OMX_IN OMX_COMMANDTYPE cmd,
   2598         OMX_IN OMX_U32 param1,
   2599         OMX_IN OMX_PTR cmdData
   2600         )
   2601 {
   2602     (void) hComp;
   2603     (void) cmdData;
   2604     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
   2605     if (m_state == OMX_StateInvalid) {
   2606         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
   2607         return OMX_ErrorInvalidState;
   2608     }
   2609     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   2610             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   2611         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
   2612                 "to invalid port: %u", (unsigned int)param1);
   2613         return OMX_ErrorBadPortIndex;
   2614     }
   2615 
   2616     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   2617     sem_wait(&m_cmd_lock);
   2618     DEBUG_PRINT_LOW("send_command: Command Processed");
   2619     return OMX_ErrorNone;
   2620 }
   2621 
   2622 /* ======================================================================
   2623    FUNCTION
   2624    omx_vdec::SendCommand
   2625 
   2626    DESCRIPTION
   2627    Returns zero if all the buffers released..
   2628 
   2629    PARAMETERS
   2630    None.
   2631 
   2632    RETURN VALUE
   2633    true/false
   2634 
   2635    ========================================================================== */
   2636 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   2637         OMX_IN OMX_COMMANDTYPE cmd,
   2638         OMX_IN OMX_U32 param1,
   2639         OMX_IN OMX_PTR cmdData
   2640         )
   2641 {
   2642     (void) hComp;
   2643     (void) cmdData;
   2644     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2645     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   2646     int bFlag = 1,sem_posted = 0,ret=0;
   2647 
   2648     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
   2649     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
   2650             m_state, eState);
   2651 
   2652     if (cmd == OMX_CommandStateSet) {
   2653         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   2654         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   2655         /***************************/
   2656         /* Current State is Loaded */
   2657         /***************************/
   2658         if (m_state == OMX_StateLoaded) {
   2659             if (eState == OMX_StateIdle) {
   2660                 //if all buffers are allocated or all ports disabled
   2661                 if (allocate_done() ||
   2662                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   2663                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
   2664                 } else {
   2665                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
   2666                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   2667                     // Skip the event notification
   2668                     bFlag = 0;
   2669                 }
   2670             }
   2671             /* Requesting transition from Loaded to Loaded */
   2672             else if (eState == OMX_StateLoaded) {
   2673                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
   2674                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2675                         OMX_COMPONENT_GENERATE_EVENT);
   2676                 eRet = OMX_ErrorSameState;
   2677             }
   2678             /* Requesting transition from Loaded to WaitForResources */
   2679             else if (eState == OMX_StateWaitForResources) {
   2680                 /* Since error is None , we will post an event
   2681                    at the end of this function definition */
   2682                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
   2683             }
   2684             /* Requesting transition from Loaded to Executing */
   2685             else if (eState == OMX_StateExecuting) {
   2686                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
   2687                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2688                         OMX_COMPONENT_GENERATE_EVENT);
   2689                 eRet = OMX_ErrorIncorrectStateTransition;
   2690             }
   2691             /* Requesting transition from Loaded to Pause */
   2692             else if (eState == OMX_StatePause) {
   2693                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
   2694                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2695                         OMX_COMPONENT_GENERATE_EVENT);
   2696                 eRet = OMX_ErrorIncorrectStateTransition;
   2697             }
   2698             /* Requesting transition from Loaded to Invalid */
   2699             else if (eState == OMX_StateInvalid) {
   2700                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
   2701                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2702                 eRet = OMX_ErrorInvalidState;
   2703             } else {
   2704                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
   2705                         eState);
   2706                 eRet = OMX_ErrorBadParameter;
   2707             }
   2708         }
   2709 
   2710         /***************************/
   2711         /* Current State is IDLE */
   2712         /***************************/
   2713         else if (m_state == OMX_StateIdle) {
   2714             if (eState == OMX_StateLoaded) {
   2715                 if (release_done()) {
   2716                     /*
   2717                        Since error is None , we will post an event at the end
   2718                        of this function definition
   2719                      */
   2720                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
   2721                 } else {
   2722                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
   2723                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   2724                     // Skip the event notification
   2725                     bFlag = 0;
   2726                 }
   2727             }
   2728             /* Requesting transition from Idle to Executing */
   2729             else if (eState == OMX_StateExecuting) {
   2730                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2731                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   2732                 bFlag = 1;
   2733                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2734                 m_state=OMX_StateExecuting;
   2735                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
   2736             }
   2737             /* Requesting transition from Idle to Idle */
   2738             else if (eState == OMX_StateIdle) {
   2739                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
   2740                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2741                         OMX_COMPONENT_GENERATE_EVENT);
   2742                 eRet = OMX_ErrorSameState;
   2743             }
   2744             /* Requesting transition from Idle to WaitForResources */
   2745             else if (eState == OMX_StateWaitForResources) {
   2746                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
   2747                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2748                         OMX_COMPONENT_GENERATE_EVENT);
   2749                 eRet = OMX_ErrorIncorrectStateTransition;
   2750             }
   2751             /* Requesting transition from Idle to Pause */
   2752             else if (eState == OMX_StatePause) {
   2753                 /*To pause the Video core we need to start the driver*/
   2754                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   2755                       NULL) < */0) {
   2756                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
   2757                     omx_report_error ();
   2758                     eRet = OMX_ErrorHardware;
   2759                 } else {
   2760                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   2761                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
   2762                     bFlag = 0;
   2763                 }
   2764             }
   2765             /* Requesting transition from Idle to Invalid */
   2766             else if (eState == OMX_StateInvalid) {
   2767                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
   2768                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2769                 eRet = OMX_ErrorInvalidState;
   2770             } else {
   2771                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
   2772                 eRet = OMX_ErrorBadParameter;
   2773             }
   2774         }
   2775 
   2776         /******************************/
   2777         /* Current State is Executing */
   2778         /******************************/
   2779         else if (m_state == OMX_StateExecuting) {
   2780             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
   2781             /* Requesting transition from Executing to Idle */
   2782             if (eState == OMX_StateIdle) {
   2783                 /* Since error is None , we will post an event
   2784                    at the end of this function definition
   2785                  */
   2786                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
   2787                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2788                 if (!sem_posted) {
   2789                     sem_posted = 1;
   2790                     sem_post (&m_cmd_lock);
   2791                     execute_omx_flush(OMX_ALL);
   2792                 }
   2793                 bFlag = 0;
   2794             }
   2795             /* Requesting transition from Executing to Paused */
   2796             else if (eState == OMX_StatePause) {
   2797                 DEBUG_PRINT_LOW("PAUSE Command Issued");
   2798                 m_state = OMX_StatePause;
   2799                 bFlag = 1;
   2800             }
   2801             /* Requesting transition from Executing to Loaded */
   2802             else if (eState == OMX_StateLoaded) {
   2803                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
   2804                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2805                         OMX_COMPONENT_GENERATE_EVENT);
   2806                 eRet = OMX_ErrorIncorrectStateTransition;
   2807             }
   2808             /* Requesting transition from Executing to WaitForResources */
   2809             else if (eState == OMX_StateWaitForResources) {
   2810                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
   2811                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2812                         OMX_COMPONENT_GENERATE_EVENT);
   2813                 eRet = OMX_ErrorIncorrectStateTransition;
   2814             }
   2815             /* Requesting transition from Executing to Executing */
   2816             else if (eState == OMX_StateExecuting) {
   2817                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
   2818                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2819                         OMX_COMPONENT_GENERATE_EVENT);
   2820                 eRet = OMX_ErrorSameState;
   2821             }
   2822             /* Requesting transition from Executing to Invalid */
   2823             else if (eState == OMX_StateInvalid) {
   2824                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
   2825                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2826                 eRet = OMX_ErrorInvalidState;
   2827             } else {
   2828                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
   2829                 eRet = OMX_ErrorBadParameter;
   2830             }
   2831         }
   2832         /***************************/
   2833         /* Current State is Pause  */
   2834         /***************************/
   2835         else if (m_state == OMX_StatePause) {
   2836             /* Requesting transition from Pause to Executing */
   2837             if (eState == OMX_StateExecuting) {
   2838                 DEBUG_PRINT_LOW("Pause --> Executing");
   2839                 m_state = OMX_StateExecuting;
   2840                 bFlag = 1;
   2841             }
   2842             /* Requesting transition from Pause to Idle */
   2843             else if (eState == OMX_StateIdle) {
   2844                 /* Since error is None , we will post an event
   2845                    at the end of this function definition */
   2846                 DEBUG_PRINT_LOW("Pause --> Idle");
   2847                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2848                 if (!sem_posted) {
   2849                     sem_posted = 1;
   2850                     sem_post (&m_cmd_lock);
   2851                     execute_omx_flush(OMX_ALL);
   2852                 }
   2853                 bFlag = 0;
   2854             }
   2855             /* Requesting transition from Pause to loaded */
   2856             else if (eState == OMX_StateLoaded) {
   2857                 DEBUG_PRINT_ERROR("Pause --> loaded");
   2858                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2859                         OMX_COMPONENT_GENERATE_EVENT);
   2860                 eRet = OMX_ErrorIncorrectStateTransition;
   2861             }
   2862             /* Requesting transition from Pause to WaitForResources */
   2863             else if (eState == OMX_StateWaitForResources) {
   2864                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
   2865                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2866                         OMX_COMPONENT_GENERATE_EVENT);
   2867                 eRet = OMX_ErrorIncorrectStateTransition;
   2868             }
   2869             /* Requesting transition from Pause to Pause */
   2870             else if (eState == OMX_StatePause) {
   2871                 DEBUG_PRINT_ERROR("Pause --> Pause");
   2872                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2873                         OMX_COMPONENT_GENERATE_EVENT);
   2874                 eRet = OMX_ErrorSameState;
   2875             }
   2876             /* Requesting transition from Pause to Invalid */
   2877             else if (eState == OMX_StateInvalid) {
   2878                 DEBUG_PRINT_ERROR("Pause --> Invalid");
   2879                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2880                 eRet = OMX_ErrorInvalidState;
   2881             } else {
   2882                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
   2883                 eRet = OMX_ErrorBadParameter;
   2884             }
   2885         }
   2886         /***************************/
   2887         /* Current State is WaitForResources  */
   2888         /***************************/
   2889         else if (m_state == OMX_StateWaitForResources) {
   2890             /* Requesting transition from WaitForResources to Loaded */
   2891             if (eState == OMX_StateLoaded) {
   2892                 /* Since error is None , we will post an event
   2893                    at the end of this function definition */
   2894                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
   2895             }
   2896             /* Requesting transition from WaitForResources to WaitForResources */
   2897             else if (eState == OMX_StateWaitForResources) {
   2898                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
   2899                 post_event(OMX_EventError,OMX_ErrorSameState,
   2900                         OMX_COMPONENT_GENERATE_EVENT);
   2901                 eRet = OMX_ErrorSameState;
   2902             }
   2903             /* Requesting transition from WaitForResources to Executing */
   2904             else if (eState == OMX_StateExecuting) {
   2905                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
   2906                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2907                         OMX_COMPONENT_GENERATE_EVENT);
   2908                 eRet = OMX_ErrorIncorrectStateTransition;
   2909             }
   2910             /* Requesting transition from WaitForResources to Pause */
   2911             else if (eState == OMX_StatePause) {
   2912                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
   2913                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2914                         OMX_COMPONENT_GENERATE_EVENT);
   2915                 eRet = OMX_ErrorIncorrectStateTransition;
   2916             }
   2917             /* Requesting transition from WaitForResources to Invalid */
   2918             else if (eState == OMX_StateInvalid) {
   2919                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
   2920                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2921                 eRet = OMX_ErrorInvalidState;
   2922             }
   2923             /* Requesting transition from WaitForResources to Loaded -
   2924                is NOT tested by Khronos TS */
   2925 
   2926         } else {
   2927             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
   2928             eRet = OMX_ErrorBadParameter;
   2929         }
   2930     }
   2931     /********************************/
   2932     /* Current State is Invalid */
   2933     /*******************************/
   2934     else if (m_state == OMX_StateInvalid) {
   2935         /* State Transition from Inavlid to any state */
   2936         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   2937                     || OMX_StateIdle || OMX_StateExecuting
   2938                     || OMX_StatePause || OMX_StateInvalid)) {
   2939             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
   2940             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   2941                     OMX_COMPONENT_GENERATE_EVENT);
   2942             eRet = OMX_ErrorInvalidState;
   2943         }
   2944     } else if (cmd == OMX_CommandFlush) {
   2945         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
   2946                 "with param1: %u", (unsigned int)param1);
   2947 #ifdef _MSM8974_
   2948         send_codec_config();
   2949 #endif
   2950         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
   2951                     param1 == OMX_ALL)) {
   2952             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
   2953                struct timespec ts;
   2954 
   2955                clock_gettime(CLOCK_REALTIME, &ts);
   2956                ts.tv_sec += 2;
   2957                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
   2958                        m_queued_codec_config_count);
   2959                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
   2960                if (sem_timedwait(&m_safe_flush, &ts)) {
   2961                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
   2962                }
   2963                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
   2964             }
   2965         }
   2966 
   2967         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2968             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   2969         }
   2970         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2971             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   2972         }
   2973         if (!sem_posted) {
   2974             sem_posted = 1;
   2975             DEBUG_PRINT_LOW("Set the Semaphore");
   2976             sem_post (&m_cmd_lock);
   2977             execute_omx_flush(param1);
   2978         }
   2979         bFlag = 0;
   2980     } else if ( cmd == OMX_CommandPortEnable) {
   2981         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
   2982                 "with param1: %u", (unsigned int)param1);
   2983         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2984             m_inp_bEnabled = OMX_TRUE;
   2985 
   2986             if ( (m_state == OMX_StateLoaded &&
   2987                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2988                     || allocate_input_done()) {
   2989                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   2990                         OMX_COMPONENT_GENERATE_EVENT);
   2991             } else {
   2992                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   2993                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2994                 // Skip the event notification
   2995                 bFlag = 0;
   2996             }
   2997         }
   2998         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   2999             DEBUG_PRINT_LOW("Enable output Port command recieved");
   3000             m_out_bEnabled = OMX_TRUE;
   3001 
   3002             if ( (m_state == OMX_StateLoaded &&
   3003                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   3004                     || (allocate_output_done())) {
   3005                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   3006                         OMX_COMPONENT_GENERATE_EVENT);
   3007 
   3008             } else {
   3009                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   3010                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   3011                 // Skip the event notification
   3012                 bFlag = 0;
   3013                 /* enable/disable downscaling if required */
   3014                 ret = decide_downscalar();
   3015                 if (ret) {
   3016                     DEBUG_PRINT_LOW("decide_downscalar failed\n");
   3017                 }
   3018             }
   3019         }
   3020     } else if (cmd == OMX_CommandPortDisable) {
   3021         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
   3022                 "with param1: %u", (unsigned int)param1);
   3023         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   3024             codec_config_flag = false;
   3025             m_inp_bEnabled = OMX_FALSE;
   3026             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3027                     && release_input_done()) {
   3028                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   3029                         OMX_COMPONENT_GENERATE_EVENT);
   3030             } else {
   3031                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   3032                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3033                     if (!sem_posted) {
   3034                         sem_posted = 1;
   3035                         sem_post (&m_cmd_lock);
   3036                     }
   3037                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   3038                 }
   3039 
   3040                 // Skip the event notification
   3041                 bFlag = 0;
   3042             }
   3043         }
   3044         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   3045             m_out_bEnabled = OMX_FALSE;
   3046             DEBUG_PRINT_LOW("Disable output Port command recieved");
   3047             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   3048                     && release_output_done()) {
   3049                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   3050                         OMX_COMPONENT_GENERATE_EVENT);
   3051             } else {
   3052                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   3053                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   3054                     if (!sem_posted) {
   3055                         sem_posted = 1;
   3056                         sem_post (&m_cmd_lock);
   3057                     }
   3058                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   3059                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   3060                 }
   3061                 // Skip the event notification
   3062                 bFlag = 0;
   3063 
   3064             }
   3065         }
   3066     } else {
   3067         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
   3068         eRet = OMX_ErrorNotImplemented;
   3069     }
   3070     if (eRet == OMX_ErrorNone && bFlag) {
   3071         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   3072     }
   3073     if (!sem_posted) {
   3074         sem_post(&m_cmd_lock);
   3075     }
   3076 
   3077     return eRet;
   3078 }
   3079 
   3080 /* ======================================================================
   3081    FUNCTION
   3082    omx_vdec::ExecuteOmxFlush
   3083 
   3084    DESCRIPTION
   3085    Executes the OMX flush.
   3086 
   3087    PARAMETERS
   3088    flushtype - input flush(1)/output flush(0)/ both.
   3089 
   3090    RETURN VALUE
   3091    true/false
   3092 
   3093    ========================================================================== */
   3094 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   3095 {
   3096     bool bRet = false;
   3097     struct v4l2_plane plane;
   3098     struct v4l2_buffer v4l2_buf;
   3099     struct v4l2_decoder_cmd dec;
   3100     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
   3101     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   3102     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   3103 
   3104     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   3105 
   3106     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   3107         output_flush_progress = true;
   3108         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3109     } else {
   3110         /* XXX: The driver/hardware does not support flushing of individual ports
   3111          * in all states. So we pretty much need to flush both ports internally,
   3112          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   3113          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   3114          * we automatically omit sending the FLUSH done for the "opposite" port. */
   3115         input_flush_progress = true;
   3116         output_flush_progress = true;
   3117         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   3118         request_perf_level(VIDC_TURBO);
   3119     }
   3120 
   3121     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   3122         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
   3123         bRet = false;
   3124     }
   3125 
   3126     return bRet;
   3127 }
   3128 /*=========================================================================
   3129 FUNCTION : execute_output_flush
   3130 
   3131 DESCRIPTION
   3132 Executes the OMX flush at OUTPUT PORT.
   3133 
   3134 PARAMETERS
   3135 None.
   3136 
   3137 RETURN VALUE
   3138 true/false
   3139 ==========================================================================*/
   3140 bool omx_vdec::execute_output_flush()
   3141 {
   3142     unsigned long p1 = 0; // Parameter - 1
   3143     unsigned long p2 = 0; // Parameter - 2
   3144     unsigned long ident = 0;
   3145     bool bRet = true;
   3146 
   3147     /*Generate FBD for all Buffers in the FTBq*/
   3148     pthread_mutex_lock(&m_lock);
   3149     DEBUG_PRINT_LOW("Initiate Output Flush");
   3150 
   3151     //reset last render TS
   3152     if(m_last_rendered_TS > 0) {
   3153         m_last_rendered_TS = 0;
   3154     }
   3155 
   3156     while (m_ftb_q.m_size) {
   3157         DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
   3158                 m_ftb_q.m_size,pending_output_buffers);
   3159         m_ftb_q.pop_entry(&p1,&p2,&ident);
   3160         DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
   3161         if (ident == m_fill_output_msg ) {
   3162             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
   3163         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   3164             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
   3165         }
   3166     }
   3167     pthread_mutex_unlock(&m_lock);
   3168     output_flush_progress = false;
   3169 
   3170     if (arbitrary_bytes) {
   3171         prev_ts = LLONG_MAX;
   3172         rst_prev_ts = true;
   3173     }
   3174     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   3175     return bRet;
   3176 }
   3177 /*=========================================================================
   3178 FUNCTION : execute_input_flush
   3179 
   3180 DESCRIPTION
   3181 Executes the OMX flush at INPUT PORT.
   3182 
   3183 PARAMETERS
   3184 None.
   3185 
   3186 RETURN VALUE
   3187 true/false
   3188 ==========================================================================*/
   3189 bool omx_vdec::execute_input_flush()
   3190 {
   3191     unsigned       i =0;
   3192     unsigned long p1 = 0; // Parameter - 1
   3193     unsigned long p2 = 0; // Parameter - 2
   3194     unsigned long ident = 0;
   3195     bool bRet = true;
   3196 
   3197     /*Generate EBD for all Buffers in the ETBq*/
   3198     DEBUG_PRINT_LOW("Initiate Input Flush");
   3199 
   3200     pthread_mutex_lock(&m_lock);
   3201     DEBUG_PRINT_LOW("Check if the Queue is empty");
   3202     while (m_etb_q.m_size) {
   3203         m_etb_q.pop_entry(&p1,&p2,&ident);
   3204 
   3205         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   3206             DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   3207             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   3208         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   3209             pending_input_buffers++;
   3210             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   3211                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   3212             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   3213         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   3214             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   3215                     (OMX_BUFFERHEADERTYPE *)p1);
   3216             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   3217         }
   3218     }
   3219     time_stamp_dts.flush_timestamp();
   3220     /*Check if Heap Buffers are to be flushed*/
   3221     if (arbitrary_bytes && !(codec_config_flag)) {
   3222         DEBUG_PRINT_LOW("Reset all the variables before flusing");
   3223         h264_scratch.nFilledLen = 0;
   3224         nal_count = 0;
   3225         look_ahead_nal = false;
   3226         frame_count = 0;
   3227         h264_last_au_ts = LLONG_MAX;
   3228         h264_last_au_flags = 0;
   3229         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   3230         m_demux_entries = 0;
   3231         DEBUG_PRINT_LOW("Initialize parser");
   3232         if (m_frame_parser.mutils) {
   3233             m_frame_parser.mutils->initialize_frame_checking_environment();
   3234         }
   3235 
   3236         while (m_input_pending_q.m_size) {
   3237             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   3238             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   3239         }
   3240 
   3241         if (psource_frame) {
   3242             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   3243             psource_frame = NULL;
   3244         }
   3245 
   3246         if (pdest_frame) {
   3247             pdest_frame->nFilledLen = 0;
   3248             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
   3249                     (unsigned int)NULL);
   3250             pdest_frame = NULL;
   3251         }
   3252         m_frame_parser.flush();
   3253     } else if (codec_config_flag) {
   3254         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   3255                 "is not sent to the driver yet");
   3256     }
   3257     pthread_mutex_unlock(&m_lock);
   3258     input_flush_progress = false;
   3259     if (!arbitrary_bytes) {
   3260         prev_ts = LLONG_MAX;
   3261         rst_prev_ts = true;
   3262     }
   3263 #ifdef _ANDROID_
   3264     if (m_debug_timestamp) {
   3265         m_timestamp_list.reset_ts_list();
   3266     }
   3267 #endif
   3268     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   3269     return bRet;
   3270 }
   3271 
   3272 /*=========================================================================
   3273 FUNCTION : notify_flush_done
   3274 DESCRIPTION
   3275 Notifies flush done to the OMX Client.
   3276 PARAMETERS
   3277 ctxt -- Context information related to the self..
   3278 RETURN VALUE
   3279 NONE
   3280 ==========================================================================*/
   3281 void omx_vdec::notify_flush_done(void *ctxt) {
   3282     omx_vdec *pThis = (omx_vdec *) ctxt;
   3283     if (!pThis->input_flush_progress && !pThis->output_flush_progress) {
   3284         if (BITMASK_PRESENT(&pThis->m_flags,
   3285                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   3286             DEBUG_PRINT_LOW("Notify Output Flush done");
   3287             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   3288             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3289                 OMX_EventCmdComplete,OMX_CommandFlush,
   3290                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   3291         }
   3292 
   3293         if (BITMASK_PRESENT(&pThis->m_flags,
   3294                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
   3295             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   3296             DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
   3297             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   3298                     OMX_EventCmdComplete,OMX_CommandFlush,
   3299                     OMX_CORE_INPUT_PORT_INDEX,NULL );
   3300         }
   3301     }
   3302 }
   3303 
   3304 /* ======================================================================
   3305    FUNCTION
   3306    omx_vdec::SendCommandEvent
   3307 
   3308    DESCRIPTION
   3309    Send the event to decoder pipe.  This is needed to generate the callbacks
   3310    in decoder thread context.
   3311 
   3312    PARAMETERS
   3313    None.
   3314 
   3315    RETURN VALUE
   3316    true/false
   3317 
   3318    ========================================================================== */
   3319 bool omx_vdec::post_event(unsigned long p1,
   3320         unsigned long p2,
   3321         unsigned long id)
   3322 {
   3323     bool bRet = false;
   3324 
   3325     /* Just drop messages typically generated by hardware (w/o client request),
   3326      * if we've reported an error to client. */
   3327     if (m_error_propogated) {
   3328         switch (id) {
   3329             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   3330             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   3331                 DEBUG_PRINT_ERROR("Dropping message %lx "
   3332                         "since client expected to be in error state", id);
   3333                 return false;
   3334             default:
   3335                 /* whatever */
   3336                 break;
   3337         }
   3338     }
   3339 
   3340     pthread_mutex_lock(&m_lock);
   3341 
   3342     if (id == m_fill_output_msg ||
   3343             id == OMX_COMPONENT_GENERATE_FBD ||
   3344             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG ||
   3345             id == OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH) {
   3346         m_ftb_q.insert_entry(p1,p2,id);
   3347     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   3348             id == OMX_COMPONENT_GENERATE_EBD ||
   3349             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY ||
   3350             id == OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH) {
   3351         m_etb_q.insert_entry(p1,p2,id);
   3352     } else {
   3353         m_cmd_q.insert_entry(p1,p2,id);
   3354     }
   3355 
   3356     bRet = true;
   3357     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   3358     post_message(this, id);
   3359 
   3360     pthread_mutex_unlock(&m_lock);
   3361 
   3362     return bRet;
   3363 }
   3364 
   3365 OMX_ERRORTYPE omx_vdec::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   3366 {
   3367     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3368     if (!profileLevelType)
   3369         return OMX_ErrorBadParameter;
   3370 
   3371     if (profileLevelType->nPortIndex == 0) {
   3372         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3373             if (profileLevelType->nProfileIndex == 0) {
   3374                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3375                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3376 
   3377             } else if (profileLevelType->nProfileIndex == 1) {
   3378                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   3379                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3380             } else if (profileLevelType->nProfileIndex == 2) {
   3381                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   3382                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel51;
   3383             } else {
   3384                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3385                         (unsigned int)profileLevelType->nProfileIndex);
   3386                 eRet = OMX_ErrorNoMore;
   3387             }
   3388         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3389             if (profileLevelType->nProfileIndex == 0) {
   3390                 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
   3391                 profileLevelType->eLevel   = QOMX_VIDEO_MVCLevel51;
   3392             } else {
   3393                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3394                                 (unsigned int)profileLevelType->nProfileIndex);
   3395                 eRet = OMX_ErrorNoMore;
   3396             }
   3397         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3398             if (profileLevelType->nProfileIndex == 0) {
   3399                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
   3400                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3401             } else if (profileLevelType->nProfileIndex == 1) {
   3402                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain10;
   3403                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   3404             } else {
   3405                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3406                         (unsigned int)profileLevelType->nProfileIndex);
   3407                 eRet = OMX_ErrorNoMore;
   3408             }
   3409         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   3410             if (profileLevelType->nProfileIndex == 0) {
   3411                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   3412                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   3413             } else {
   3414                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3415                                 (unsigned int)profileLevelType->nProfileIndex);
   3416                 eRet = OMX_ErrorNoMore;
   3417             }
   3418         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3419             if (profileLevelType->nProfileIndex == 0) {
   3420                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   3421                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3422             } else if (profileLevelType->nProfileIndex == 1) {
   3423                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   3424                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   3425             } else {
   3426                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3427                                 (unsigned int)profileLevelType->nProfileIndex);
   3428                 eRet = OMX_ErrorNoMore;
   3429             }
   3430         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3431                 !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   3432             eRet = OMX_ErrorNoMore;
   3433         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3434             if (profileLevelType->nProfileIndex == 0) {
   3435                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   3436                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3437             } else if (profileLevelType->nProfileIndex == 1) {
   3438                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   3439                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   3440             } else {
   3441                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   3442                                 (unsigned int)profileLevelType->nProfileIndex);
   3443                 eRet = OMX_ErrorNoMore;
   3444             }
   3445         } else {
   3446             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
   3447             eRet = OMX_ErrorNoMore;
   3448         }
   3449     } else {
   3450         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
   3451                           (unsigned int)profileLevelType->nPortIndex);
   3452         eRet = OMX_ErrorBadPortIndex;
   3453     }
   3454     return eRet;
   3455 }
   3456 
   3457 /* ======================================================================
   3458    FUNCTION
   3459    omx_vdec::GetParameter
   3460 
   3461    DESCRIPTION
   3462    OMX Get Parameter method implementation
   3463 
   3464    PARAMETERS
   3465    <TBD>.
   3466 
   3467    RETURN VALUE
   3468    Error None if successful.
   3469 
   3470    ========================================================================== */
   3471 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3472         OMX_IN OMX_INDEXTYPE paramIndex,
   3473         OMX_INOUT OMX_PTR     paramData)
   3474 {
   3475     (void) hComp;
   3476     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3477 
   3478     DEBUG_PRINT_LOW("get_parameter:");
   3479     if (m_state == OMX_StateInvalid) {
   3480         DEBUG_PRINT_ERROR("Get Param in Invalid State");
   3481         return OMX_ErrorInvalidState;
   3482     }
   3483     if (paramData == NULL) {
   3484         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
   3485         return OMX_ErrorBadParameter;
   3486     }
   3487     switch ((unsigned long)paramIndex) {
   3488         case OMX_IndexParamPortDefinition: {
   3489                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3490                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   3491                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3492                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   3493                                decide_dpb_buffer_mode(is_down_scalar_enabled);
   3494                                eRet = update_portdef(portDefn);
   3495                                if (eRet == OMX_ErrorNone)
   3496                                    m_port_def = *portDefn;
   3497                                break;
   3498                            }
   3499         case OMX_IndexParamVideoInit: {
   3500                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3501                               OMX_PORT_PARAM_TYPE *portParamType =
   3502                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3503                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   3504 
   3505                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3506                               portParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3507                               portParamType->nPorts           = 2;
   3508                               portParamType->nStartPortNumber = 0;
   3509                               break;
   3510                           }
   3511         case OMX_IndexParamVideoPortFormat: {
   3512                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3513                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3514                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3515                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   3516 
   3517                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   3518                                 portFmt->nSize             = sizeof(OMX_VIDEO_PARAM_PORTFORMATTYPE);
   3519 
   3520                                 if (0 == portFmt->nPortIndex) {
   3521                                     if (0 == portFmt->nIndex) {
   3522                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   3523                                         portFmt->eCompressionFormat = eCompressionFormat;
   3524                                     } else {
   3525                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3526                                                 " NoMore compression formats");
   3527                                         eRet =  OMX_ErrorNoMore;
   3528                                     }
   3529                                 } else if (1 == portFmt->nPortIndex) {
   3530                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   3531 
   3532                                     // Distinguish non-surface mode from normal playback use-case based on
   3533                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
   3534                                     // For non-android, use the default list
   3535                                     // Also use default format-list if FLEXIBLE YUV is supported,
   3536                                     // as the client negotiates the standard color-format if it needs to
   3537                                     bool useNonSurfaceMode = false;
   3538 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
   3539                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
   3540 #endif
   3541                                     if (is_thulium_v1) {
   3542                                         portFmt->eColorFormat = getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3543                                     } else {
   3544                                         portFmt->eColorFormat = useNonSurfaceMode ?
   3545                                             getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
   3546                                             getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3547                                     }
   3548 
   3549                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
   3550                                         eRet = OMX_ErrorNoMore;
   3551                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3552                                                 " NoMore Color formats");
   3553                                     }
   3554                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
   3555                                 } else {
   3556                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   3557                                             (int)portFmt->nPortIndex);
   3558                                     eRet = OMX_ErrorBadPortIndex;
   3559                                 }
   3560                                 break;
   3561                             }
   3562                             /*Component should support this port definition*/
   3563         case OMX_IndexParamAudioInit: {
   3564                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3565                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   3566                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3567                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   3568                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3569                               audioPortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3570                               audioPortParamType->nPorts           = 0;
   3571                               audioPortParamType->nStartPortNumber = 0;
   3572                               break;
   3573                           }
   3574                           /*Component should support this port definition*/
   3575         case OMX_IndexParamImageInit: {
   3576                               VALIDATE_OMX_PARAM_DATA(paramData, OMX_PORT_PARAM_TYPE);
   3577                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   3578                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3579                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   3580                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3581                               imagePortParamType->nSize = sizeof(OMX_PORT_PARAM_TYPE);
   3582                               imagePortParamType->nPorts           = 0;
   3583                               imagePortParamType->nStartPortNumber = 0;
   3584                               break;
   3585 
   3586                           }
   3587                           /*Component should support this port definition*/
   3588         case OMX_IndexParamOtherInit: {
   3589                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
   3590                                       paramIndex);
   3591                               eRet =OMX_ErrorUnsupportedIndex;
   3592                               break;
   3593                           }
   3594         case OMX_IndexParamStandardComponentRole: {
   3595                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   3596                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3597                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3598                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   3599                                   comp_role->nSize = sizeof(*comp_role);
   3600 
   3601                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
   3602                                           paramIndex);
   3603                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   3604                                           OMX_MAX_STRINGNAME_SIZE);
   3605                                   break;
   3606                               }
   3607                               /* Added for parameter test */
   3608         case OMX_IndexParamPriorityMgmt: {
   3609                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   3610                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   3611                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   3612                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   3613                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   3614                              priorityMgmType->nSize = sizeof(OMX_PRIORITYMGMTTYPE);
   3615 
   3616                              break;
   3617                          }
   3618                          /* Added for parameter test */
   3619         case OMX_IndexParamCompBufferSupplier: {
   3620                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   3621                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   3622                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3623                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   3624 
   3625                                    bufferSupplierType->nSize = sizeof(OMX_PARAM_BUFFERSUPPLIERTYPE);
   3626                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   3627                                    if (0 == bufferSupplierType->nPortIndex)
   3628                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3629                                    else if (1 == bufferSupplierType->nPortIndex)
   3630                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3631                                    else
   3632                                        eRet = OMX_ErrorBadPortIndex;
   3633 
   3634 
   3635                                    break;
   3636                                }
   3637         case OMX_IndexParamVideoAvc: {
   3638                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
   3639                                      paramIndex);
   3640                              break;
   3641                          }
   3642         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3643                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
   3644                                      paramIndex);
   3645                              break;
   3646                          }
   3647         case OMX_IndexParamVideoH263: {
   3648                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   3649                                       paramIndex);
   3650                               break;
   3651                           }
   3652         case OMX_IndexParamVideoMpeg4: {
   3653                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   3654                                        paramIndex);
   3655                                break;
   3656                            }
   3657         case OMX_IndexParamVideoMpeg2: {
   3658                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   3659                                        paramIndex);
   3660                                break;
   3661                            }
   3662         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   3663                                         VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3664                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
   3665                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   3666                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   3667                                         eRet = get_supported_profile_level(profileLevelType);
   3668                                         break;
   3669                                     }
   3670 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3671         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   3672                                         VALIDATE_OMX_PARAM_DATA(paramData, GetAndroidNativeBufferUsageParams);
   3673                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   3674                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   3675                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3676 
   3677                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
   3678                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   3679                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   3680                                             } else {
   3681                                                 nativeBuffersUsage->nUsage = GRALLOC_USAGE_PRIVATE_UNCACHED;
   3682                                             }
   3683                                         } else {
   3684                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   3685                                             eRet = OMX_ErrorBadParameter;
   3686                                         }
   3687                                     }
   3688                                     break;
   3689 #endif
   3690 
   3691 #ifdef FLEXYUV_SUPPORTED
   3692         case OMX_QcomIndexFlexibleYUVDescription: {
   3693                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
   3694                 VALIDATE_OMX_PARAM_DATA(paramData, DescribeColorFormatParams);
   3695                 eRet = describeColorFormat(paramData);
   3696                 break;
   3697             }
   3698 #endif
   3699         case OMX_IndexParamVideoProfileLevelCurrent: {
   3700              VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   3701              OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3702              struct v4l2_control profile_control, level_control;
   3703 
   3704              switch (drv_ctx.decoder_format) {
   3705                  case VDEC_CODECTYPE_H264:
   3706                      profile_control.id = V4L2_CID_MPEG_VIDEO_H264_PROFILE;
   3707                      level_control.id = V4L2_CID_MPEG_VIDEO_H264_LEVEL;
   3708                      break;
   3709                  default:
   3710                      DEBUG_PRINT_ERROR("get_param of OMX_IndexParamVideoProfileLevelCurrent only available for H264");
   3711                      eRet = OMX_ErrorNotImplemented;
   3712                      break;
   3713              }
   3714 
   3715              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &profile_control)) {
   3716                 switch ((enum v4l2_mpeg_video_h264_profile)profile_control.value) {
   3717                     case V4L2_MPEG_VIDEO_H264_PROFILE_BASELINE:
   3718                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_BASELINE:
   3719                         pParam->eProfile = OMX_VIDEO_AVCProfileBaseline;
   3720                         break;
   3721                     case V4L2_MPEG_VIDEO_H264_PROFILE_MAIN:
   3722                         pParam->eProfile = OMX_VIDEO_AVCProfileMain;
   3723                         break;
   3724                     case V4L2_MPEG_VIDEO_H264_PROFILE_EXTENDED:
   3725                         pParam->eProfile = OMX_VIDEO_AVCProfileExtended;
   3726                         break;
   3727                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH:
   3728                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh;
   3729                         break;
   3730                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10:
   3731                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh10;
   3732                         break;
   3733                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422:
   3734                         pParam->eProfile = OMX_VIDEO_AVCProfileHigh422;
   3735                         break;
   3736                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_PREDICTIVE:
   3737                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_10_INTRA:
   3738                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_422_INTRA:
   3739                     case V4L2_MPEG_VIDEO_H264_PROFILE_HIGH_444_INTRA:
   3740                     case V4L2_MPEG_VIDEO_H264_PROFILE_CAVLC_444_INTRA:
   3741                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_BASELINE:
   3742                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH:
   3743                     case V4L2_MPEG_VIDEO_H264_PROFILE_SCALABLE_HIGH_INTRA:
   3744                     case V4L2_MPEG_VIDEO_H264_PROFILE_STEREO_HIGH:
   3745                     case V4L2_MPEG_VIDEO_H264_PROFILE_MULTIVIEW_HIGH:
   3746                     case V4L2_MPEG_VIDEO_H264_PROFILE_CONSTRAINED_HIGH:
   3747                         eRet = OMX_ErrorUnsupportedIndex;
   3748                         break;
   3749                 }
   3750              } else {
   3751                  eRet = OMX_ErrorUnsupportedIndex;
   3752              }
   3753 
   3754 
   3755              if (!eRet && !ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &level_control)) {
   3756                 switch ((enum v4l2_mpeg_video_h264_level)level_control.value) {
   3757                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_0:
   3758                         pParam->eLevel = OMX_VIDEO_AVCLevel1;
   3759                         break;
   3760                     case V4L2_MPEG_VIDEO_H264_LEVEL_1B:
   3761                         pParam->eLevel = OMX_VIDEO_AVCLevel1b;
   3762                         break;
   3763                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_1:
   3764                         pParam->eLevel = OMX_VIDEO_AVCLevel11;
   3765                         break;
   3766                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_2:
   3767                         pParam->eLevel = OMX_VIDEO_AVCLevel12;
   3768                         break;
   3769                     case V4L2_MPEG_VIDEO_H264_LEVEL_1_3:
   3770                         pParam->eLevel = OMX_VIDEO_AVCLevel13;
   3771                         break;
   3772                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_0:
   3773                         pParam->eLevel = OMX_VIDEO_AVCLevel2;
   3774                         break;
   3775                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_1:
   3776                         pParam->eLevel = OMX_VIDEO_AVCLevel21;
   3777                         break;
   3778                     case V4L2_MPEG_VIDEO_H264_LEVEL_2_2:
   3779                         pParam->eLevel = OMX_VIDEO_AVCLevel22;
   3780                         break;
   3781                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_0:
   3782                         pParam->eLevel = OMX_VIDEO_AVCLevel3;
   3783                         break;
   3784                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_1:
   3785                         pParam->eLevel = OMX_VIDEO_AVCLevel31;
   3786                         break;
   3787                     case V4L2_MPEG_VIDEO_H264_LEVEL_3_2:
   3788                         pParam->eLevel = OMX_VIDEO_AVCLevel32;
   3789                         break;
   3790                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_0:
   3791                         pParam->eLevel = OMX_VIDEO_AVCLevel4;
   3792                         break;
   3793                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_1:
   3794                         pParam->eLevel = OMX_VIDEO_AVCLevel41;
   3795                         break;
   3796                     case V4L2_MPEG_VIDEO_H264_LEVEL_4_2:
   3797                         pParam->eLevel = OMX_VIDEO_AVCLevel42;
   3798                         break;
   3799                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_0:
   3800                         pParam->eLevel = OMX_VIDEO_AVCLevel5;
   3801                         break;
   3802                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_1:
   3803                         pParam->eLevel = OMX_VIDEO_AVCLevel51;
   3804                     case V4L2_MPEG_VIDEO_H264_LEVEL_5_2:
   3805                         pParam->eLevel = OMX_VIDEO_AVCLevel52;
   3806                         break;
   3807                 }
   3808              } else {
   3809                  eRet = OMX_ErrorUnsupportedIndex;
   3810              }
   3811 
   3812              break;
   3813 
   3814          }
   3815         default: {
   3816                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
   3817                  eRet =OMX_ErrorUnsupportedIndex;
   3818              }
   3819 
   3820     }
   3821 
   3822     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
   3823             drv_ctx.video_resolution.frame_width,
   3824             drv_ctx.video_resolution.frame_height,
   3825             drv_ctx.video_resolution.stride,
   3826             drv_ctx.video_resolution.scan_lines);
   3827 
   3828     return eRet;
   3829 }
   3830 
   3831 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3832 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   3833 {
   3834     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   3835     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3836     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   3837 
   3838     if ((params == NULL) ||
   3839             (params->nativeBuffer == NULL) ||
   3840             (params->nativeBuffer->handle == NULL) ||
   3841             !m_enable_android_native_buffers)
   3842         return OMX_ErrorBadParameter;
   3843     m_use_android_native_buffers = OMX_TRUE;
   3844     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   3845     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   3846     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   3847         OMX_U8 *buffer = NULL;
   3848         if (!secure_mode) {
   3849             buffer = (OMX_U8*)mmap(0, handle->size,
   3850                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   3851             if (buffer == MAP_FAILED) {
   3852                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   3853                 return OMX_ErrorInsufficientResources;
   3854             }
   3855         }
   3856         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   3857     } else {
   3858         eRet = OMX_ErrorBadParameter;
   3859     }
   3860     return eRet;
   3861 }
   3862 #endif
   3863 
   3864 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
   3865     struct v4l2_control control;
   3866     struct v4l2_format fmt;
   3867     control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   3868     control.value = 1;
   3869     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3870     if (rc < 0) {
   3871         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   3872         return OMX_ErrorHardware;
   3873     }
   3874     m_smoothstreaming_mode = true;
   3875     return OMX_ErrorNone;
   3876 }
   3877 
   3878 /* ======================================================================
   3879    FUNCTION
   3880    omx_vdec::Setparameter
   3881 
   3882    DESCRIPTION
   3883    OMX Set Parameter method implementation.
   3884 
   3885    PARAMETERS
   3886    <TBD>.
   3887 
   3888    RETURN VALUE
   3889    OMX Error None if successful.
   3890 
   3891    ========================================================================== */
   3892 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3893         OMX_IN OMX_INDEXTYPE paramIndex,
   3894         OMX_IN OMX_PTR        paramData)
   3895 {
   3896     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3897     int ret=0;
   3898     struct v4l2_format fmt;
   3899 #ifdef _ANDROID_
   3900     char property_value[PROPERTY_VALUE_MAX] = {0};
   3901 #endif
   3902     if (m_state == OMX_StateInvalid) {
   3903         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3904         return OMX_ErrorInvalidState;
   3905     }
   3906     if (paramData == NULL) {
   3907         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   3908         return OMX_ErrorBadParameter;
   3909     }
   3910     if ((m_state != OMX_StateLoaded) &&
   3911             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   3912             (m_out_bEnabled == OMX_TRUE) &&
   3913             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   3914             (m_inp_bEnabled == OMX_TRUE)) {
   3915         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3916         return OMX_ErrorIncorrectStateOperation;
   3917     }
   3918     switch ((unsigned long)paramIndex) {
   3919         case OMX_IndexParamPortDefinition: {
   3920                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_PORTDEFINITIONTYPE);
   3921                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   3922                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3923                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   3924                                //been called.
   3925                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
   3926                                        (int)portDefn->format.video.nFrameHeight,
   3927                                        (int)portDefn->format.video.nFrameWidth);
   3928 
   3929                                if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   3930                                    DEBUG_PRINT_ERROR("ERROR: Buffers requested exceeds max limit %d",
   3931                                                           portDefn->nBufferCountActual);
   3932                                    eRet = OMX_ErrorBadParameter;
   3933                                    break;
   3934                                }
   3935                                if (OMX_DirOutput == portDefn->eDir) {
   3936                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
   3937                                    bool port_format_changed = false;
   3938                                    m_display_id = portDefn->format.video.pNativeWindow;
   3939                                    unsigned int buffer_size;
   3940                                    /* update output port resolution with client supplied dimensions
   3941                                       in case scaling is enabled, else it follows input resolution set
   3942                                    */
   3943                                    decide_dpb_buffer_mode(is_down_scalar_enabled);
   3944                                    if (is_down_scalar_enabled) {
   3945                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
   3946                                                (unsigned int)portDefn->format.video.nFrameWidth,
   3947                                                (unsigned int)portDefn->format.video.nFrameHeight);
   3948                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   3949                                                portDefn->format.video.nFrameWidth != 0x0) {
   3950                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3951                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3952                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3953                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   3954                                            if (ret) {
   3955                                                DEBUG_PRINT_ERROR("Get Resolution failed");
   3956                                                eRet = OMX_ErrorHardware;
   3957                                                break;
   3958                                            }
   3959                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
   3960                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
   3961                                                    port_format_changed = true;
   3962                                            }
   3963                                            update_resolution(portDefn->format.video.nFrameWidth,
   3964                                                    portDefn->format.video.nFrameHeight,
   3965                                                    portDefn->format.video.nFrameWidth,
   3966                                                    portDefn->format.video.nFrameHeight);
   3967 
   3968                                            /* set crop info */
   3969                                            rectangle.nLeft = 0;
   3970                                            rectangle.nTop = 0;
   3971                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
   3972                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
   3973 
   3974                                            eRet = is_video_session_supported();
   3975                                            if (eRet)
   3976                                                break;
   3977                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3978                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3979                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   3980                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   3981                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3982                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
   3983                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
   3984                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   3985                                            if (ret) {
   3986                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   3987                                                eRet = OMX_ErrorUnsupportedSetting;
   3988                                            } else
   3989                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   3990                                        }
   3991 
   3992                                        if (eRet) {
   3993                                            break;
   3994                                        }
   3995 
   3996                                        if (secure_mode) {
   3997                                            struct v4l2_control control;
   3998                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
   3999                                            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   4000                                                DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
   4001                                                eRet = OMX_ErrorHardware;
   4002                                            } else {
   4003                                                /* This is a workaround for a bug in fw which uses stride
   4004                                                 * and slice instead of width and height to check against
   4005                                                 * the threshold.
   4006                                                 */
   4007                                                OMX_U32 stride, slice;
   4008                                                if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   4009                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
   4010                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
   4011                                                } else if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   4012                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameWidth);
   4013                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, portDefn->format.video.nFrameHeight);
   4014                                                } else {
   4015                                                    stride = portDefn->format.video.nFrameWidth;
   4016                                                    slice = portDefn->format.video.nFrameHeight;
   4017                                                }
   4018 
   4019                                                DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
   4020                                                DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
   4021 
   4022                                                if (stride * slice <= (OMX_U32)control.value) {
   4023                                                    secure_scaling_to_non_secure_opb = true;
   4024                                                    DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
   4025                                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
   4026                                                    control.value = 1;
   4027                                                    if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   4028                                                        DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
   4029                                                        eRet = OMX_ErrorUnsupportedSetting;
   4030                                                    }
   4031                                                }
   4032                                            }
   4033                                        }
   4034                                    }
   4035 
   4036                                    if (eRet) {
   4037                                        break;
   4038                                    }
   4039 
   4040                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4041                                        DEBUG_PRINT_ERROR("Requested o/p buf count (%u) exceeds limit (%u)",
   4042                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4043                                        eRet = OMX_ErrorBadParameter;
   4044                                    } else if (!client_buffers.get_buffer_req(buffer_size)) {
   4045                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
   4046                                        eRet = OMX_ErrorBadParameter;
   4047                                    } else if (!port_format_changed) {
   4048 
   4049                                        // Buffer count can change only when port is unallocated
   4050                                        if (m_out_mem_ptr &&
   4051                                                 (portDefn->nBufferCountActual != drv_ctx.op_buf.actualcount ||
   4052                                                 portDefn->nBufferSize != drv_ctx.op_buf.buffer_size)) {
   4053 
   4054                                            DEBUG_PRINT_ERROR("Cannot change o/p buffer count since all buffers are not freed yet !");
   4055                                            eRet = OMX_ErrorInvalidState;
   4056                                            break;
   4057                                        }
   4058 
   4059                                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
   4060                                                portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size ) {
   4061                                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
   4062                                            drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
   4063                                            drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
   4064                                            drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
   4065                                                drv_ctx.extradata_info.buffer_size;
   4066                                            eRet = set_buffer_req(&drv_ctx.op_buf);
   4067                                            if (eRet == OMX_ErrorNone)
   4068                                                m_port_def = *portDefn;
   4069                                        } else {
   4070                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
   4071                                                    drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size,
   4072                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4073                                            eRet = OMX_ErrorBadParameter;
   4074                                        }
   4075                                    }
   4076                                } else if (OMX_DirInput == portDefn->eDir) {
   4077                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
   4078                                    bool port_format_changed = false;
   4079                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   4080                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   4081                                        // Frame rate only should be set if this is a "known value" or to
   4082                                        // activate ts prediction logic (arbitrary mode only) sending input
   4083                                        // timestamps with max value (LLONG_MAX).
   4084                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
   4085                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
   4086                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   4087                                                drv_ctx.frame_rate.fps_denominator);
   4088                                        if (!drv_ctx.frame_rate.fps_numerator) {
   4089                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   4090                                            drv_ctx.frame_rate.fps_numerator = 30;
   4091                                        }
   4092                                        if (drv_ctx.frame_rate.fps_denominator)
   4093                                            drv_ctx.frame_rate.fps_numerator = (int)
   4094                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   4095                                        drv_ctx.frame_rate.fps_denominator = 1;
   4096                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   4097                                            drv_ctx.frame_rate.fps_numerator;
   4098                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
   4099                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   4100                                                (float)drv_ctx.frame_rate.fps_denominator);
   4101 
   4102                                        struct v4l2_outputparm oparm;
   4103                                        /*XXX: we're providing timing info as seconds per frame rather than frames
   4104                                         * per second.*/
   4105                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   4106                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   4107 
   4108                                        struct v4l2_streamparm sparm;
   4109                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4110                                        sparm.parm.output = oparm;
   4111                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   4112                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
   4113                                            eRet = OMX_ErrorHardware;
   4114                                            break;
   4115                                        }
   4116                                        m_perf_control.request_cores(frm_int);
   4117                                    }
   4118 
   4119                                    if (drv_ctx.video_resolution.frame_height !=
   4120                                            portDefn->format.video.nFrameHeight ||
   4121                                            drv_ctx.video_resolution.frame_width  !=
   4122                                            portDefn->format.video.nFrameWidth) {
   4123                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
   4124                                                (unsigned int)portDefn->format.video.nFrameWidth,
   4125                                                (unsigned int)portDefn->format.video.nFrameHeight);
   4126                                        port_format_changed = true;
   4127                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
   4128                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
   4129                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
   4130                                            if (m_smoothstreaming_mode &&
   4131                                                    ((frameWidth * frameHeight) <
   4132                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
   4133                                                frameWidth = m_smoothstreaming_width;
   4134                                                frameHeight = m_smoothstreaming_height;
   4135                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
   4136                                                        "for adaptive-playback/smooth-streaming",
   4137                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
   4138                                            }
   4139                                            update_resolution(frameWidth, frameHeight,
   4140                                                    frameWidth, frameHeight);
   4141                                            eRet = is_video_session_supported();
   4142                                            if (eRet)
   4143                                                break;
   4144                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4145                                            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4146                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4147                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4148                                            fmt.fmt.pix_mp.pixelformat = output_capability;
   4149                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",fmt.fmt.pix_mp.height,fmt.fmt.pix_mp.width);
   4150                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4151                                            if (ret) {
   4152                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   4153                                                eRet = OMX_ErrorUnsupportedSetting;
   4154                                            } else {
   4155                                                if (!is_down_scalar_enabled)
   4156                                                    eRet = get_buffer_req(&drv_ctx.op_buf);
   4157                                            }
   4158                                        }
   4159                                    }
   4160                                    if (m_custom_buffersize.input_buffersize
   4161                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
   4162                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
   4163                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
   4164                                        eRet = OMX_ErrorBadParameter;
   4165                                        break;
   4166                                    }
   4167                                    if (portDefn->nBufferCountActual > MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   4168                                        DEBUG_PRINT_ERROR("Requested i/p buf count (%u) exceeds limit (%u)",
   4169                                                portDefn->nBufferCountActual, MAX_NUM_INPUT_OUTPUT_BUFFERS);
   4170                                        eRet = OMX_ErrorBadParameter;
   4171                                        break;
   4172                                    }
   4173                                    // Buffer count can change only when port is unallocated
   4174                                    if (m_inp_mem_ptr &&
   4175                                             (portDefn->nBufferCountActual != drv_ctx.ip_buf.actualcount ||
   4176                                             portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size)) {
   4177                                        DEBUG_PRINT_ERROR("Cannot change i/p buffer count since all buffers are not freed yet !");
   4178                                        eRet = OMX_ErrorInvalidState;
   4179                                        break;
   4180                                    }
   4181 
   4182                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   4183                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   4184                                        port_format_changed = true;
   4185                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   4186                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   4187                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   4188                                            (~(buffer_prop->alignment - 1));
   4189                                        eRet = set_buffer_req(buffer_prop);
   4190                                    }
   4191                                    if (false == port_format_changed) {
   4192                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
   4193                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
   4194                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   4195                                        eRet = OMX_ErrorBadParameter;
   4196                                    }
   4197                                } else if (portDefn->eDir ==  OMX_DirMax) {
   4198                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   4199                                            (int)portDefn->nPortIndex);
   4200                                    eRet = OMX_ErrorBadPortIndex;
   4201                                }
   4202                            }
   4203                            break;
   4204         case OMX_IndexParamVideoPortFormat: {
   4205                                 VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PORTFORMATTYPE);
   4206                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   4207                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   4208                                 int ret=0;
   4209                                 struct v4l2_format fmt;
   4210                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
   4211                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
   4212 
   4213                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
   4214                                 if (1 == portFmt->nPortIndex) {
   4215                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4216                                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   4217                                     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   4218                                     enum vdec_output_fromat op_format;
   4219                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4220                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   4221                                             portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4222                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
   4223                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
   4224                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   4225                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   4226                                     } else if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4227                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4228                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12_UBWC;
   4229                                     } else
   4230                                         eRet = OMX_ErrorBadParameter;
   4231 
   4232                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   4233                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   4234                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12_UBWC;
   4235                                     } else {
   4236                                         fmt.fmt.pix_mp.pixelformat = capture_capability = V4L2_PIX_FMT_NV12;
   4237                                     }
   4238 
   4239                                     if (eRet == OMX_ErrorNone) {
   4240                                         drv_ctx.output_format = op_format;
   4241                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   4242                                         if (ret) {
   4243                                             DEBUG_PRINT_ERROR("Set output format failed");
   4244                                             eRet = OMX_ErrorUnsupportedSetting;
   4245                                             /*TODO: How to handle this case */
   4246                                         } else {
   4247                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   4248                                         }
   4249                                     }
   4250                                     if (eRet == OMX_ErrorNone) {
   4251                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   4252                                             DEBUG_PRINT_ERROR("Set color format failed");
   4253                                             eRet = OMX_ErrorBadParameter;
   4254                                         }
   4255                                     }
   4256                                 }
   4257                             }
   4258                             break;
   4259 
   4260         case OMX_QcomIndexPortDefn: {
   4261                             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PARAM_PORTDEFINITIONTYPE);
   4262                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   4263                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   4264                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
   4265                                     (unsigned int)portFmt->nFramePackingFormat);
   4266 
   4267                             /* Input port */
   4268                             if (portFmt->nPortIndex == 0) {
   4269                                 // arbitrary_bytes mode cannot be changed arbitrarily since this controls how:
   4270                                 //   - headers are allocated and
   4271                                 //   - headers-indices are derived
   4272                                 // Avoid changing arbitrary_bytes when the port is already allocated
   4273                                 if (m_inp_mem_ptr) {
   4274                                     DEBUG_PRINT_ERROR("Cannot change arbitrary-bytes-mode since input port is not free!");
   4275                                     return OMX_ErrorUnsupportedSetting;
   4276                                 }
   4277                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   4278                                     if (secure_mode || m_input_pass_buffer_fd) {
   4279                                         arbitrary_bytes = false;
   4280                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode");
   4281                                         eRet = OMX_ErrorUnsupportedSetting;
   4282                                     } else {
   4283                                         arbitrary_bytes = true;
   4284                                     }
   4285                                 } else if (portFmt->nFramePackingFormat ==
   4286                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   4287                                     arbitrary_bytes = false;
   4288 #ifdef _ANDROID_
   4289                                     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   4290                                     if (atoi(property_value)) {
   4291                                         DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
   4292                                         arbitrary_bytes = true;
   4293                                     }
   4294 #endif
   4295                                 } else {
   4296                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
   4297                                             (unsigned int)portFmt->nFramePackingFormat);
   4298                                     eRet = OMX_ErrorUnsupportedSetting;
   4299                                 }
   4300                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4301                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
   4302                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   4303                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   4304                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   4305                                     m_out_mem_region_smi = OMX_TRUE;
   4306                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4307                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
   4308                                         m_use_output_pmem = OMX_TRUE;
   4309                                     }
   4310                                 }
   4311                             }
   4312                         }
   4313                         if (is_thulium_v1 && !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   4314                                     OMX_MAX_STRINGNAME_SIZE)) {
   4315                             arbitrary_bytes = true;
   4316                             DEBUG_PRINT_HIGH("Force arbitrary_bytes to true for h264");
   4317                         }
   4318                         break;
   4319 
   4320         case OMX_IndexParamStandardComponentRole: {
   4321                                   VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_COMPONENTROLETYPE);
   4322                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   4323                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   4324                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
   4325                                           comp_role->cRole);
   4326 
   4327                                   if ((m_state == OMX_StateLoaded)&&
   4328                                           !BITMASK_PRESENT(&m_flags, OMX_COMPONENT_IDLE_PENDING)) {
   4329                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   4330                                   } else {
   4331                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4332                                       return OMX_ErrorIncorrectStateOperation;
   4333                                   }
   4334 
   4335                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4336                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE)) {
   4337                                           strlcpy((char*)m_cRole, "video_decoder.avc", OMX_MAX_STRINGNAME_SIZE);
   4338                                       } else {
   4339                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4340                                           eRet =OMX_ErrorUnsupportedSetting;
   4341                                       }
   4342                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4343                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   4344                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   4345                                       } else {
   4346                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4347                                           eRet = OMX_ErrorUnsupportedSetting;
   4348                                       }
   4349                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4350                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   4351                                           strlcpy((char*)m_cRole, "video_decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE);
   4352                                       } else {
   4353                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4354                                           eRet = OMX_ErrorUnsupportedSetting;
   4355                                       }
   4356                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4357                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   4358                                           strlcpy((char*)m_cRole, "video_decoder.h263", OMX_MAX_STRINGNAME_SIZE);
   4359                                       } else {
   4360                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4361                                           eRet =OMX_ErrorUnsupportedSetting;
   4362                                       }
   4363                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4364                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   4365                                           strlcpy((char*)m_cRole, "video_decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE);
   4366                                       } else {
   4367                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4368                                           eRet = OMX_ErrorUnsupportedSetting;
   4369                                       }
   4370                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE)) ||
   4371                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
   4372                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
   4373                                         ) {
   4374                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE)) {
   4375                                           strlcpy((char*)m_cRole, "video_decoder.divx", OMX_MAX_STRINGNAME_SIZE);
   4376                                       } else {
   4377                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4378                                           eRet =OMX_ErrorUnsupportedSetting;
   4379                                       }
   4380                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) ||
   4381                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE))
   4382                                         ) {
   4383                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   4384                                           strlcpy((char*)m_cRole, "video_decoder.vc1", OMX_MAX_STRINGNAME_SIZE);
   4385                                       } else {
   4386                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4387                                           eRet =OMX_ErrorUnsupportedSetting;
   4388                                       }
   4389                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   4390                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE) ||
   4391                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4392                                           strlcpy((char*)m_cRole, "video_decoder.vp8", OMX_MAX_STRINGNAME_SIZE);
   4393                                       } else {
   4394                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4395                                           eRet = OMX_ErrorUnsupportedSetting;
   4396                                       }
   4397                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9", OMX_MAX_STRINGNAME_SIZE)) {
   4398                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE) ||
   4399                                               !strncmp((const char*)comp_role->cRole, "video_decoder.vpx", OMX_MAX_STRINGNAME_SIZE)) {
   4400                                           strlcpy((char*)m_cRole, "video_decoder.vp9", OMX_MAX_STRINGNAME_SIZE);
   4401                                       } else {
   4402                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4403                                           eRet = OMX_ErrorUnsupportedSetting;
   4404                                       }
   4405                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4406                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   4407                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   4408                                       } else {
   4409                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   4410                                           eRet = OMX_ErrorUnsupportedSetting;
   4411                                       }
   4412                                   } else {
   4413                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
   4414                                       eRet = OMX_ErrorInvalidComponentName;
   4415                                   }
   4416                                   break;
   4417                               }
   4418 
   4419         case OMX_IndexParamPriorityMgmt: {
   4420                              VALIDATE_OMX_PARAM_DATA(paramData, OMX_PRIORITYMGMTTYPE);
   4421                              if (m_state != OMX_StateLoaded) {
   4422                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   4423                                  return OMX_ErrorIncorrectStateOperation;
   4424                              }
   4425                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   4426                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
   4427                                      (unsigned int)priorityMgmtype->nGroupID);
   4428 
   4429                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
   4430                                      (unsigned int)priorityMgmtype->nGroupPriority);
   4431 
   4432                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   4433                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   4434 
   4435                              break;
   4436                          }
   4437 
   4438         case OMX_IndexParamCompBufferSupplier: {
   4439                                    VALIDATE_OMX_PARAM_DATA(paramData, OMX_PARAM_BUFFERSUPPLIERTYPE);
   4440                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   4441                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
   4442                                            bufferSupplierType->eBufferSupplier);
   4443                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   4444                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   4445 
   4446                                    else
   4447 
   4448                                        eRet = OMX_ErrorBadPortIndex;
   4449 
   4450                                    break;
   4451 
   4452                                }
   4453         case OMX_IndexParamVideoAvc: {
   4454                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
   4455                                      paramIndex);
   4456                              break;
   4457                          }
   4458         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   4459                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
   4460                                      paramIndex);
   4461                              break;
   4462                         }
   4463         case OMX_IndexParamVideoH263: {
   4464                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   4465                                       paramIndex);
   4466                               break;
   4467                           }
   4468         case OMX_IndexParamVideoMpeg4: {
   4469                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   4470                                        paramIndex);
   4471                                break;
   4472                            }
   4473         case OMX_IndexParamVideoMpeg2: {
   4474                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   4475                                        paramIndex);
   4476                                break;
   4477                            }
   4478         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   4479                                      VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_DECODER_PICTURE_ORDER);
   4480                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   4481                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   4482                                      struct v4l2_control control;
   4483                                      int pic_order,rc=0;
   4484                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
   4485                                              pictureOrder->eOutputPictureOrder);
   4486                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   4487                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   4488                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   4489                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4490                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   4491                                      } else
   4492                                          eRet = OMX_ErrorBadParameter;
   4493                                      if (eRet == OMX_ErrorNone) {
   4494                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4495                                          control.value = pic_order;
   4496                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4497                                          if (rc) {
   4498                                              DEBUG_PRINT_ERROR("Set picture order failed");
   4499                                              eRet = OMX_ErrorUnsupportedSetting;
   4500                                          }
   4501                                      }
   4502                                      m_decode_order_mode =
   4503                                             pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER;
   4504                                      break;
   4505                                  }
   4506         case OMX_QcomIndexParamConcealMBMapExtraData:
   4507                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4508                                eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   4509                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4510                                break;
   4511         case OMX_QcomIndexParamFrameInfoExtraData:
   4512                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4513                                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   4514                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4515                                break;
   4516         case OMX_ExtraDataFrameDimension:
   4517                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4518                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
   4519                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4520                                break;
   4521         case OMX_QcomIndexParamInterlaceExtraData:
   4522                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4523                                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   4524                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4525                                break;
   4526         case OMX_QcomIndexParamH264TimeInfo:
   4527                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4528                                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   4529                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4530                                break;
   4531         case OMX_QcomIndexParamVideoFramePackingExtradata:
   4532                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4533                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
   4534                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4535                                break;
   4536         case OMX_QcomIndexParamVideoQPExtraData:
   4537                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4538                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4539                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4540                                break;
   4541         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
   4542                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4543                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
   4544                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4545                                break;
   4546         case OMX_QcomIndexEnableExtnUserData:
   4547                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4548                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
   4549                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4550                                 break;
   4551         case OMX_QTIIndexParamVQZipSEIExtraData:
   4552                                VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4553                                 eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4554                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4555                                 break;
   4556         case OMX_QcomIndexParamVideoDivx: {
   4557                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   4558                           }
   4559                           break;
   4560         case OMX_QcomIndexPlatformPvt: {
   4561                                VALIDATE_OMX_PARAM_DATA(paramData, OMX_QCOM_PLATFORMPRIVATE_EXTN);
   4562                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
   4563                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   4564                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4565                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   4566                                    eRet = OMX_ErrorUnsupportedSetting;
   4567                                } else {
   4568                                    m_out_pvt_entry_pmem = OMX_TRUE;
   4569                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   4570                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
   4571                                        m_use_output_pmem = OMX_TRUE;
   4572                                    }
   4573                                }
   4574 
   4575                            }
   4576                            break;
   4577         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   4578                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   4579                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   4580                                        struct v4l2_control control;
   4581                                        int rc;
   4582                                        drv_ctx.idr_only_decoding = 1;
   4583                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   4584                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   4585                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4586                                        if (rc) {
   4587                                            DEBUG_PRINT_ERROR("Set picture order failed");
   4588                                            eRet = OMX_ErrorUnsupportedSetting;
   4589                                        } else {
   4590                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   4591                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   4592                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4593                                            if (rc) {
   4594                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
   4595                                                eRet = OMX_ErrorUnsupportedSetting;
   4596                                            }
   4597                                            /*Setting sync frame decoding on driver might change buffer
   4598                                             * requirements so update them here*/
   4599                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   4600                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
   4601                                                eRet = OMX_ErrorUnsupportedSetting;
   4602                                            }
   4603                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   4604                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
   4605                                                eRet = OMX_ErrorUnsupportedSetting;
   4606                                            }
   4607                                        }
   4608                                    }
   4609                                    break;
   4610 
   4611         case OMX_QcomIndexParamIndexExtraDataType: {
   4612                                     VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXEXTRADATATYPE);
   4613                                     QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   4614                                     if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   4615                                             (extradataIndexType->bEnabled == OMX_TRUE) &&
   4616                                             (extradataIndexType->nPortIndex == 1)) {
   4617                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
   4618                                         eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   4619 
   4620                                     }
   4621                                 }
   4622                                 break;
   4623         case OMX_QcomIndexParamEnableSmoothStreaming: {
   4624 #ifndef SMOOTH_STREAMING_DISABLED
   4625                                       eRet = enable_smoothstreaming();
   4626 #else
   4627                                       eRet = OMX_ErrorUnsupportedSetting;
   4628 #endif
   4629                                   }
   4630                                   break;
   4631 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4632                                   /* Need to allow following two set_parameters even in Idle
   4633                                    * state. This is ANDROID architecture which is not in sync
   4634                                    * with openmax standard. */
   4635         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   4636                                            VALIDATE_OMX_PARAM_DATA(paramData, EnableAndroidNativeBuffersParams);
   4637                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   4638                                            if (enableNativeBuffers->nPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   4639                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers allowed only on output port!");
   4640                                                 eRet = OMX_ErrorUnsupportedSetting;
   4641                                                 break;
   4642                                            } else if (m_out_mem_ptr) {
   4643                                                 DEBUG_PRINT_ERROR("Enable/Disable android-native-buffers is not allowed since Output port is not free !");
   4644                                                 eRet = OMX_ErrorInvalidState;
   4645                                                 break;
   4646                                            }
   4647                                            if (enableNativeBuffers) {
   4648                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   4649                                            }
   4650 #if !defined(FLEXYUV_SUPPORTED)
   4651                                            if (m_enable_android_native_buffers) {
   4652                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
   4653                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
   4654                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
   4655                                                    eRet = OMX_ErrorUnsupportedSetting;
   4656                                                }
   4657                                            }
   4658 #endif
   4659                                        }
   4660                                        break;
   4661         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   4662                                        VALIDATE_OMX_PARAM_DATA(paramData, UseAndroidNativeBufferParams);
   4663                                        eRet = use_android_native_buffer(hComp, paramData);
   4664                                    }
   4665                                    break;
   4666         case OMX_GoogleAndroidIndexAllocateNativeHandle: {
   4667 
   4668                 AllocateNativeHandleParams* allocateNativeHandleParams = (AllocateNativeHandleParams *) paramData;
   4669                 VALIDATE_OMX_PARAM_DATA(paramData, AllocateNativeHandleParams);
   4670 
   4671                 if (allocateNativeHandleParams->nPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   4672                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle allowed only on input port!");
   4673                     eRet = OMX_ErrorUnsupportedSetting;
   4674                     break;
   4675                 } else if (m_inp_mem_ptr) {
   4676                     DEBUG_PRINT_ERROR("Enable/Disable allocate-native-handle is not allowed since Input port is not free !");
   4677                     eRet = OMX_ErrorInvalidState;
   4678                     break;
   4679                 }
   4680 
   4681                 if (allocateNativeHandleParams != NULL) {
   4682                     allocate_native_handle = allocateNativeHandleParams->enable;
   4683                 }
   4684             }
   4685             break;
   4686 #endif
   4687         case OMX_QcomIndexParamEnableTimeStampReorder: {
   4688                                        VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXTIMESTAMPREORDER);
   4689                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   4690                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   4691                                            if (reorder->bEnable == OMX_TRUE) {
   4692                                                frm_int =0;
   4693                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   4694                                            } else
   4695                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   4696                                        } else {
   4697                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   4698                                            if (reorder->bEnable == OMX_TRUE) {
   4699                                                eRet = OMX_ErrorUnsupportedSetting;
   4700                                            }
   4701                                        }
   4702                                    }
   4703                                    break;
   4704         case OMX_IndexParamVideoProfileLevelCurrent: {
   4705                                      VALIDATE_OMX_PARAM_DATA(paramData, OMX_VIDEO_PARAM_PROFILELEVELTYPE);
   4706                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   4707                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   4708                                      if (pParam) {
   4709                                          m_profile_lvl.eProfile = pParam->eProfile;
   4710                                          m_profile_lvl.eLevel = pParam->eLevel;
   4711                                      }
   4712                                      break;
   4713 
   4714                                  }
   4715         case OMX_QcomIndexParamVideoMetaBufferMode:
   4716         {
   4717             VALIDATE_OMX_PARAM_DATA(paramData, StoreMetaDataInBuffersParams);
   4718             StoreMetaDataInBuffersParams *metabuffer =
   4719                 (StoreMetaDataInBuffersParams *)paramData;
   4720             if (!metabuffer) {
   4721                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   4722                 eRet = OMX_ErrorBadParameter;
   4723                 break;
   4724             }
   4725             if (m_disable_dynamic_buf_mode) {
   4726                 DEBUG_PRINT_HIGH("Dynamic buffer mode is disabled");
   4727                 eRet = OMX_ErrorUnsupportedSetting;
   4728                 break;
   4729             }
   4730             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4731 
   4732                     if (m_out_mem_ptr) {
   4733                         DEBUG_PRINT_ERROR("Enable/Disable dynamic-buffer-mode is not allowed since Output port is not free !");
   4734                         eRet = OMX_ErrorInvalidState;
   4735                         break;
   4736                     }
   4737                     //set property dynamic buffer mode to driver.
   4738                     struct v4l2_control control;
   4739                     struct v4l2_format fmt;
   4740                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   4741                     if (metabuffer->bStoreMetaData == true) {
   4742                         control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   4743                     } else {
   4744                         control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
   4745                     }
   4746                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   4747                     if (!rc) {
   4748                         DEBUG_PRINT_HIGH("%s buffer mode",
   4749                            (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
   4750                     } else {
   4751                         DEBUG_PRINT_ERROR("Failed to %s buffer mode",
   4752                            (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
   4753                     }
   4754                     dynamic_buf_mode = metabuffer->bStoreMetaData;
   4755                 } else {
   4756                     DEBUG_PRINT_ERROR(
   4757                        "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
   4758                        (unsigned int)metabuffer->nPortIndex);
   4759                     eRet = OMX_ErrorUnsupportedSetting;
   4760                 }
   4761                 break;
   4762         }
   4763         case OMX_QcomIndexParamVideoDownScalar:
   4764         {
   4765             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_INDEXDOWNSCALAR);
   4766             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
   4767             struct v4l2_control control;
   4768             int rc;
   4769             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoDownScalar %d\n", pParam->bEnable);
   4770 
   4771             if (pParam && pParam->bEnable) {
   4772                 rc = enable_downscalar();
   4773                 if (rc < 0) {
   4774                     DEBUG_PRINT_ERROR("%s: enable_downscalar failed\n", __func__);
   4775                     return OMX_ErrorUnsupportedSetting;
   4776                 }
   4777                 m_force_down_scalar = pParam->bEnable;
   4778             } else {
   4779                 rc = disable_downscalar();
   4780                 if (rc < 0) {
   4781                     DEBUG_PRINT_ERROR("%s: disable_downscalar failed\n", __func__);
   4782                     return OMX_ErrorUnsupportedSetting;
   4783                 }
   4784                 m_force_down_scalar = pParam->bEnable;
   4785             }
   4786             break;
   4787         }
   4788 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   4789         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
   4790         {
   4791             VALIDATE_OMX_PARAM_DATA(paramData, PrepareForAdaptivePlaybackParams);
   4792             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
   4793             PrepareForAdaptivePlaybackParams* pParams =
   4794                     (PrepareForAdaptivePlaybackParams *) paramData;
   4795             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4796                 if (!pParams->bEnable) {
   4797                     return OMX_ErrorNone;
   4798                 }
   4799                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
   4800                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
   4801                     DEBUG_PRINT_ERROR(
   4802                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
   4803                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
   4804                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
   4805                     eRet = OMX_ErrorBadParameter;
   4806                 } else {
   4807                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
   4808                 }
   4809             } else {
   4810                 DEBUG_PRINT_ERROR(
   4811                         "Prepare for adaptive playback supported only on output port");
   4812                 eRet = OMX_ErrorBadParameter;
   4813             }
   4814             break;
   4815         }
   4816 
   4817         case OMX_QTIIndexParamVideoPreferAdaptivePlayback:
   4818         {
   4819             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4820             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVideoPreferAdaptivePlayback");
   4821             m_disable_dynamic_buf_mode = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   4822             if (m_disable_dynamic_buf_mode) {
   4823                 DEBUG_PRINT_HIGH("Prefer Adaptive Playback is set");
   4824             }
   4825             break;
   4826         }
   4827 #endif
   4828         case OMX_QcomIndexParamVideoCustomBufferSize:
   4829         {
   4830             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_VIDEO_CUSTOM_BUFFERSIZE);
   4831             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
   4832             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
   4833             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   4834                 struct v4l2_control control;
   4835                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
   4836                 control.value = pParam->nBufferSize;
   4837                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   4838                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
   4839                     eRet = OMX_ErrorUnsupportedSetting;
   4840                 } else {
   4841                     eRet = get_buffer_req(&drv_ctx.ip_buf);
   4842                     if (eRet == OMX_ErrorNone) {
   4843                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
   4844                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
   4845                             m_custom_buffersize.input_buffersize);
   4846                     } else {
   4847                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
   4848                     }
   4849                 }
   4850             } else {
   4851                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
   4852                 eRet = OMX_ErrorBadParameter;
   4853             }
   4854             break;
   4855         }
   4856         case OMX_QTIIndexParamVQZIPSEIType:
   4857         {
   4858             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE);
   4859             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamVQZIPSEIType");
   4860             OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *pParam =
   4861                 (OMX_QTI_VIDEO_PARAM_VQZIP_SEI_TYPE *)paramData;
   4862                 DEBUG_PRINT_LOW("Enable VQZIP SEI: %d", pParam->bEnable);
   4863             eRet = enable_extradata(OMX_VQZIPSEI_EXTRADATA, false,
   4864                 ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4865             if (eRet != OMX_ErrorNone) {
   4866                 DEBUG_PRINT_ERROR("ERROR: Failed to set SEI Extradata");
   4867                 eRet = OMX_ErrorBadParameter;
   4868                 client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   4869             } else {
   4870                 eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   4871                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   4872                 if (eRet != OMX_ErrorNone) {
   4873                     DEBUG_PRINT_ERROR("ERROR: Failed to set QP Extradata");
   4874                     eRet = OMX_ErrorBadParameter;
   4875                     client_extradata = client_extradata & ~OMX_VQZIPSEI_EXTRADATA;
   4876                     client_extradata = client_extradata & ~OMX_QP_EXTRADATA;
   4877                 }
   4878             }
   4879             break;
   4880         }
   4881 
   4882         case OMX_QTIIndexParamPassInputBufferFd:
   4883         {
   4884             VALIDATE_OMX_PARAM_DATA(paramData, QOMX_ENABLETYPE);
   4885             if (arbitrary_bytes) {
   4886                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamPassInputBufferFd not supported in arbitrary buffer mode");
   4887                 eRet = OMX_ErrorUnsupportedSetting;
   4888                 break;
   4889             }
   4890 
   4891             m_input_pass_buffer_fd = ((QOMX_ENABLETYPE *)paramData)->bEnable;
   4892             if (m_input_pass_buffer_fd)
   4893                 DEBUG_PRINT_LOW("Enable passing input buffer FD");
   4894             break;
   4895         }
   4896         case OMX_QTIIndexParamForceCompressedForDPB:
   4897         {
   4898             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE);
   4899             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceCompressedForDPB");
   4900             OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *pParam =
   4901                 (OMX_QTI_VIDEO_PARAM_FORCE_COMPRESSED_FOR_DPB_TYPE *)paramData;
   4902             if (m_disable_ubwc_mode) {
   4903                 DEBUG_PRINT_ERROR("OMX_QTIIndexParamForceCompressedForDPB not supported when ubwc disabled");
   4904                 eRet = OMX_ErrorUnsupportedSetting;
   4905                 break;
   4906             }
   4907             if (!paramData) {
   4908                DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceCompressedForDPB paramData NULL");
   4909                eRet = OMX_ErrorBadParameter;
   4910                break;
   4911             }
   4912 
   4913             m_force_compressed_for_dpb = pParam->bEnable;
   4914             break;
   4915         }
   4916         case OMX_QTIIndexParamForceUnCompressedForOPB:
   4917         {
   4918             VALIDATE_OMX_PARAM_DATA(paramData, OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE);
   4919             DEBUG_PRINT_LOW("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB");
   4920             OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *pParam =
   4921                 (OMX_QTI_VIDEO_PARAM_FORCE_UNCOMPRESSED_FOR_OPB_TYPE *)paramData;
   4922             if (!paramData) {
   4923                 DEBUG_PRINT_ERROR("set_parameter: OMX_QTIIndexParamForceUnCompressedForOPB paramData is NULL");
   4924                 eRet = OMX_ErrorBadParameter;
   4925                 break;
   4926             }
   4927             m_disable_ubwc_mode = pParam->bEnable;
   4928             DEBUG_PRINT_LOW("set_parameter: UBWC %s for OPB", pParam->bEnable ? "disabled" : "enabled");
   4929             break;
   4930         }
   4931 
   4932 
   4933         default: {
   4934                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
   4935                  eRet = OMX_ErrorUnsupportedIndex;
   4936              }
   4937     }
   4938     if (eRet != OMX_ErrorNone)
   4939         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
   4940     return eRet;
   4941 }
   4942 
   4943 /* ======================================================================
   4944    FUNCTION
   4945    omx_vdec::GetConfig
   4946 
   4947    DESCRIPTION
   4948    OMX Get Config Method implementation.
   4949 
   4950    PARAMETERS
   4951    <TBD>.
   4952 
   4953    RETURN VALUE
   4954    OMX Error None if successful.
   4955 
   4956    ========================================================================== */
   4957 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   4958         OMX_IN OMX_INDEXTYPE configIndex,
   4959         OMX_INOUT OMX_PTR     configData)
   4960 {
   4961     (void) hComp;
   4962     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4963 
   4964     if (m_state == OMX_StateInvalid) {
   4965         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   4966         return OMX_ErrorInvalidState;
   4967     }
   4968 
   4969     switch ((unsigned long)configIndex) {
   4970         case OMX_QcomIndexConfigInterlaced: {
   4971                                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_CONFIG_INTERLACETYPE);
   4972                                 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   4973                                     (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   4974                                 if (configFmt->nPortIndex == 1) {
   4975                                     if (configFmt->nIndex == 0) {
   4976                                         configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   4977                                     } else if (configFmt->nIndex == 1) {
   4978                                         configFmt->eInterlaceType =
   4979                                             OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   4980                                     } else if (configFmt->nIndex == 2) {
   4981                                         configFmt->eInterlaceType =
   4982                                             OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   4983                                     } else {
   4984                                         DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   4985                                                 " NoMore Interlaced formats");
   4986                                         eRet = OMX_ErrorNoMore;
   4987                                     }
   4988 
   4989                                 } else {
   4990                                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
   4991                                             (int)configFmt->nPortIndex);
   4992                                     eRet = OMX_ErrorBadPortIndex;
   4993                                 }
   4994                                 break;
   4995                             }
   4996         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
   4997                                      VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_QUERY_DECODER_INSTANCES);
   4998                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   4999                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   5000                                      decoderinstances->nNumOfInstances = 16;
   5001                                      /*TODO: How to handle this case */
   5002                                      break;
   5003                                  }
   5004         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
   5005                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   5006                                               VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   5007                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
   5008                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
   5009                                               memcpy(configFmt, &m_frame_pack_arrangement,
   5010                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   5011                                           } else {
   5012                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
   5013                                           }
   5014                                           break;
   5015                                       }
   5016         case OMX_IndexConfigCommonOutputCrop: {
   5017                                   VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_RECTTYPE);
   5018                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   5019                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   5020                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
   5021                                         rectangle.nLeft, rectangle.nTop,
   5022                                         rectangle.nWidth, rectangle.nHeight);
   5023                                   break;
   5024                               }
   5025         case OMX_QcomIndexConfigPerfLevel: {
   5026                 VALIDATE_OMX_PARAM_DATA(configData, OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL);
   5027                 struct v4l2_control control;
   5028                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   5029                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   5030 
   5031                 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5032                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   5033                     DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
   5034                     eRet = OMX_ErrorHardware;
   5035                 }
   5036 
   5037                 if (eRet == OMX_ErrorNone) {
   5038                     switch (control.value) {
   5039                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
   5040                             perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
   5041                             break;
   5042                         default:
   5043                             DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
   5044                             /* Fall through */
   5045                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
   5046                             perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
   5047                             break;
   5048                     }
   5049                 }
   5050 
   5051                 break;
   5052         }
   5053         case OMX_QcomIndexConfigH264EntropyCodingCabac: {
   5054             VALIDATE_OMX_PARAM_DATA(configData, QOMX_VIDEO_H264ENTROPYCODINGTYPE);
   5055             QOMX_VIDEO_H264ENTROPYCODINGTYPE *coding = (QOMX_VIDEO_H264ENTROPYCODINGTYPE *)configData;
   5056             struct v4l2_control control;
   5057 
   5058             if (drv_ctx.decoder_format != VDEC_CODECTYPE_H264) {
   5059                 DEBUG_PRINT_ERROR("get_config of OMX_QcomIndexConfigH264EntropyCodingCabac only available for H264");
   5060                 eRet = OMX_ErrorNotImplemented;
   5061                 break;
   5062             }
   5063 
   5064             control.id = V4L2_CID_MPEG_VIDEO_H264_ENTROPY_MODE;
   5065             if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control)) {
   5066                 coding->bCabac = (OMX_BOOL)
   5067                     (control.value == V4L2_MPEG_VIDEO_H264_ENTROPY_MODE_CABAC);
   5068                 /* We can't query driver at the moment for the cabac mode, so
   5069                  * just use 0xff...f as a place holder for future improvement */
   5070                 coding->nCabacInitIdc = ~0;
   5071             } else {
   5072                 eRet = OMX_ErrorUnsupportedIndex;
   5073             }
   5074 
   5075             break;
   5076         }
   5077         case OMX_QTIIndexConfigDescribeColorAspects:
   5078         {
   5079             VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5080             DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5081 
   5082             print_debug_color_aspects(&(m_client_color_space.sAspects), "GetConfig Client");
   5083             print_debug_color_aspects(&(m_internal_color_space.sAspects), "GetConfig Internal");
   5084 
   5085             if (params->bRequestingDataSpace) {
   5086                 DEBUG_PRINT_ERROR("Does not handle dataspace request");
   5087                 return OMX_ErrorUnsupportedSetting;
   5088             }
   5089             if (m_internal_color_space.bDataSpaceChanged == OMX_TRUE) {
   5090                 DEBUG_PRINT_LOW("Updating Client's color aspects with internal");
   5091                 memcpy(&(m_client_color_space.sAspects),
   5092                         &(m_internal_color_space.sAspects), sizeof(ColorAspects));
   5093                 m_internal_color_space.bDataSpaceChanged = OMX_FALSE;
   5094             }
   5095             memcpy(&(params->sAspects), &(m_client_color_space.sAspects), sizeof(ColorAspects));
   5096 
   5097             break;
   5098         }
   5099         case OMX_IndexConfigAndroidVendorExtension:
   5100         {
   5101             VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
   5102 
   5103             OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
   5104                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
   5105             VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
   5106             return get_vendor_extension_config(ext);
   5107         }
   5108         default:
   5109         {
   5110             DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
   5111             eRet = OMX_ErrorBadParameter;
   5112         }
   5113 
   5114     }
   5115 
   5116     return eRet;
   5117 }
   5118 
   5119 /* ======================================================================
   5120    FUNCTION
   5121    omx_vdec::SetConfig
   5122 
   5123    DESCRIPTION
   5124    OMX Set Config method implementation
   5125 
   5126    PARAMETERS
   5127    <TBD>.
   5128 
   5129    RETURN VALUE
   5130    OMX Error None if successful.
   5131    ========================================================================== */
   5132 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   5133         OMX_IN OMX_INDEXTYPE configIndex,
   5134         OMX_IN OMX_PTR        configData)
   5135 {
   5136     (void) hComp;
   5137     if (m_state == OMX_StateInvalid) {
   5138         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   5139         return OMX_ErrorInvalidState;
   5140     }
   5141 
   5142     OMX_ERRORTYPE ret = OMX_ErrorNone;
   5143     OMX_VIDEO_CONFIG_NALSIZE *pNal;
   5144 
   5145     DEBUG_PRINT_LOW("Set Config Called");
   5146 
   5147     if (configIndex == OMX_IndexConfigVideoNalSize) {
   5148         struct v4l2_control temp;
   5149         temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
   5150 
   5151         VALIDATE_OMX_PARAM_DATA(configData, OMX_VIDEO_CONFIG_NALSIZE);
   5152         pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   5153         switch (pNal->nNaluBytes) {
   5154             case 0:
   5155                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
   5156                 break;
   5157             case 2:
   5158                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
   5159                 break;
   5160             case 4:
   5161                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
   5162                 break;
   5163             default:
   5164                 return OMX_ErrorUnsupportedSetting;
   5165         }
   5166 
   5167         if (!arbitrary_bytes) {
   5168             /* In arbitrary bytes mode, the assembler strips out nal size and replaces
   5169              * with start code, so only need to notify driver in frame by frame mode */
   5170             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
   5171                 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
   5172                 return OMX_ErrorHardware;
   5173             }
   5174         }
   5175 
   5176         nal_length = pNal->nNaluBytes;
   5177         m_frame_parser.init_nal_length(nal_length);
   5178 
   5179         DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
   5180         return ret;
   5181     } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
   5182         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   5183         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
   5184 
   5185         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   5186             if (config->bEnabled) {
   5187                 if ((config->nFps >> 16) > 0) {
   5188                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
   5189                             (unsigned int)config->nFps >> 16);
   5190                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   5191                             drv_ctx.frame_rate.fps_denominator);
   5192 
   5193                     if (!drv_ctx.frame_rate.fps_numerator) {
   5194                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   5195                         drv_ctx.frame_rate.fps_numerator = 30;
   5196                     }
   5197 
   5198                     if (drv_ctx.frame_rate.fps_denominator) {
   5199                         drv_ctx.frame_rate.fps_numerator = (int)
   5200                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   5201                     }
   5202 
   5203                     drv_ctx.frame_rate.fps_denominator = 1;
   5204                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   5205                         drv_ctx.frame_rate.fps_numerator;
   5206 
   5207                     struct v4l2_outputparm oparm;
   5208                     /*XXX: we're providing timing info as seconds per frame rather than frames
   5209                      * per second.*/
   5210                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   5211                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   5212 
   5213                     struct v4l2_streamparm sparm;
   5214                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5215                     sparm.parm.output = oparm;
   5216                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   5217                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   5218                                 performance might be affected");
   5219                         ret = OMX_ErrorHardware;
   5220                     }
   5221                     client_set_fps = true;
   5222                 } else {
   5223                     DEBUG_PRINT_ERROR("Frame rate not supported.");
   5224                     ret = OMX_ErrorUnsupportedSetting;
   5225                 }
   5226             } else {
   5227                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   5228                 client_set_fps = false;
   5229             }
   5230         } else {
   5231             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   5232                     (int)config->nPortIndex);
   5233             ret = OMX_ErrorBadPortIndex;
   5234         }
   5235 
   5236         return ret;
   5237     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
   5238         OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   5239             (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   5240         struct v4l2_control control;
   5241 
   5242         DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
   5243 
   5244         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   5245 
   5246         switch (perf->ePerfLevel) {
   5247             case OMX_QCOM_PerfLevelNominal:
   5248                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   5249                 break;
   5250             case OMX_QCOM_PerfLevelTurbo:
   5251                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   5252                 break;
   5253             default:
   5254                 ret = OMX_ErrorUnsupportedSetting;
   5255                 break;
   5256         }
   5257 
   5258         if (ret == OMX_ErrorNone) {
   5259             ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5260                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5261         }
   5262 
   5263         return ret;
   5264     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPictureTypeDecode) {
   5265         OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *config =
   5266             (OMX_QCOM_VIDEO_CONFIG_PICTURE_TYPE_DECODE *)configData;
   5267         struct v4l2_control control;
   5268         DEBUG_PRINT_LOW("Set picture type decode: %d", config->eDecodeType);
   5269         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PICTYPE_DEC_MODE;
   5270 
   5271         switch (config->eDecodeType) {
   5272             case OMX_QCOM_PictypeDecode_I:
   5273                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_ON;
   5274                 break;
   5275             case OMX_QCOM_PictypeDecode_IPB:
   5276             default:
   5277                 control.value = V4L2_MPEG_VIDC_VIDEO_PICTYPE_DECODE_OFF;
   5278                 break;
   5279         }
   5280 
   5281         ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   5282                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   5283         if (ret)
   5284             DEBUG_PRINT_ERROR("Failed to set picture type decode");
   5285 
   5286         return ret;
   5287     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
   5288         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
   5289         DEBUG_PRINT_LOW("Set_config: priority %d",priority->nU32);
   5290 
   5291         struct v4l2_control control;
   5292 
   5293         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   5294         if (priority->nU32 == 0)
   5295             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
   5296         else
   5297             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   5298 
   5299         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5300             DEBUG_PRINT_ERROR("Failed to set Priority");
   5301             ret = OMX_ErrorUnsupportedSetting;
   5302         }
   5303         return ret;
   5304     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
   5305         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
   5306         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
   5307 
   5308         struct v4l2_control control;
   5309 
   5310         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
   5311         control.value = rate->nU32;
   5312 
   5313         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   5314             ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
   5315                     OMX_ErrorUnsupportedSetting;
   5316             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
   5317                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
   5318         }
   5319         return ret;
   5320 
   5321     } else if ((int)configIndex == (int)OMX_QTIIndexConfigDescribeColorAspects) {
   5322         VALIDATE_OMX_PARAM_DATA(configData, DescribeColorAspectsParams);
   5323         DescribeColorAspectsParams *params = (DescribeColorAspectsParams *)configData;
   5324         if (!DEFAULT_EXTRADATA & OMX_DISPLAY_INFO_EXTRADATA) {
   5325             enable_extradata(OMX_DISPLAY_INFO_EXTRADATA, true, true);
   5326         }
   5327 
   5328         print_debug_color_aspects(&(params->sAspects), "Set Config");
   5329         memcpy(&m_client_color_space, params, sizeof(DescribeColorAspectsParams));
   5330         return ret;
   5331     } else if ((int)configIndex == (int)OMX_IndexConfigAndroidVendorExtension) {
   5332         VALIDATE_OMX_PARAM_DATA(configData, OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE);
   5333 
   5334         OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *ext =
   5335                 reinterpret_cast<OMX_CONFIG_ANDROID_VENDOR_EXTENSIONTYPE *>(configData);
   5336         VALIDATE_OMX_VENDOR_EXTENSION_PARAM_DATA(ext);
   5337 
   5338         return set_vendor_extension_config(ext);
   5339     }
   5340 
   5341     return OMX_ErrorNotImplemented;
   5342 }
   5343 
   5344 #define extn_equals(param, extn) (!strcmp(param, extn))
   5345 
   5346 /* ======================================================================
   5347    FUNCTION
   5348    omx_vdec::GetExtensionIndex
   5349 
   5350    DESCRIPTION
   5351    OMX GetExtensionIndex method implementaion.  <TBD>
   5352 
   5353    PARAMETERS
   5354    <TBD>.
   5355 
   5356    RETURN VALUE
   5357    OMX Error None if everything successful.
   5358 
   5359    ========================================================================== */
   5360 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   5361         OMX_IN OMX_STRING      paramName,
   5362         OMX_OUT OMX_INDEXTYPE* indexType)
   5363 {
   5364     (void) hComp;
   5365     if (m_state == OMX_StateInvalid) {
   5366         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
   5367         return OMX_ErrorInvalidState;
   5368     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
   5369         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
   5370     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
   5371         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
   5372     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
   5373         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
   5374     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
   5375         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
   5376     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
   5377         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
   5378     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
   5379         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
   5380     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
   5381         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
   5382     }
   5383 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   5384     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
   5385         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   5386     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
   5387         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   5388     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
   5389         DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
   5390         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   5391     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
   5392         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   5393     } else if (extn_equals(paramName, "OMX.google.android.index.allocateNativeHandle")) {
   5394         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexAllocateNativeHandle;
   5395     }
   5396 #endif
   5397     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   5398         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   5399     }
   5400 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   5401     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
   5402         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
   5403     } else if (extn_equals(paramName, OMX_QTI_INDEX_PARAM_VIDEO_PREFER_ADAPTIVE_PLAYBACK)) {
   5404         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamVideoPreferAdaptivePlayback;
   5405     }
   5406 #endif
   5407 #ifdef FLEXYUV_SUPPORTED
   5408     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
   5409         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
   5410     }
   5411 #endif
   5412     else if (extn_equals(paramName, "OMX.QCOM.index.param.video.PassInputBufferFd")) {
   5413         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamPassInputBufferFd;
   5414     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceCompressedForDPB")) {
   5415         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceCompressedForDPB;
   5416     } else if (extn_equals(paramName, "OMX.QTI.index.param.video.ForceUnCompressedForOPB")) {
   5417         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexParamForceUnCompressedForOPB;
   5418     } else if (extn_equals(paramName, "OMX.google.android.index.describeColorAspects")) {
   5419         *indexType = (OMX_INDEXTYPE)OMX_QTIIndexConfigDescribeColorAspects;
   5420     } else {
   5421         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
   5422         return OMX_ErrorNotImplemented;
   5423     }
   5424     return OMX_ErrorNone;
   5425 }
   5426 
   5427 /* ======================================================================
   5428    FUNCTION
   5429    omx_vdec::GetState
   5430 
   5431    DESCRIPTION
   5432    Returns the state information back to the caller.<TBD>
   5433 
   5434    PARAMETERS
   5435    <TBD>.
   5436 
   5437    RETURN VALUE
   5438    Error None if everything is successful.
   5439    ========================================================================== */
   5440 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   5441         OMX_OUT OMX_STATETYPE* state)
   5442 {
   5443     (void) hComp;
   5444     *state = m_state;
   5445     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   5446     return OMX_ErrorNone;
   5447 }
   5448 
   5449 /* ======================================================================
   5450    FUNCTION
   5451    omx_vdec::ComponentTunnelRequest
   5452 
   5453    DESCRIPTION
   5454    OMX Component Tunnel Request method implementation. <TBD>
   5455 
   5456    PARAMETERS
   5457    None.
   5458 
   5459    RETURN VALUE
   5460    OMX Error None if everything successful.
   5461 
   5462    ========================================================================== */
   5463 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   5464         OMX_IN OMX_U32                        port,
   5465         OMX_IN OMX_HANDLETYPE        peerComponent,
   5466         OMX_IN OMX_U32                    peerPort,
   5467         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   5468 {
   5469     (void) hComp;
   5470     (void) port;
   5471     (void) peerComponent;
   5472     (void) peerPort;
   5473     (void) tunnelSetup;
   5474     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
   5475     return OMX_ErrorNotImplemented;
   5476 }
   5477 
   5478 /* ======================================================================
   5479    FUNCTION
   5480    omx_vdec::UseOutputBuffer
   5481 
   5482    DESCRIPTION
   5483    Helper function for Use buffer in the input pin
   5484 
   5485    PARAMETERS
   5486    None.
   5487 
   5488    RETURN VALUE
   5489    true/false
   5490 
   5491    ========================================================================== */
   5492 OMX_ERRORTYPE omx_vdec::allocate_extradata()
   5493 {
   5494 #ifdef USE_ION
   5495     if (drv_ctx.extradata_info.buffer_size) {
   5496         if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
   5497             munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5498             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5499             free_ion_memory(&drv_ctx.extradata_info.ion);
   5500         }
   5501         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
   5502         drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
   5503                 drv_ctx.extradata_info.size, 4096,
   5504                 &drv_ctx.extradata_info.ion.ion_alloc_data,
   5505                 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
   5506         if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
   5507             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
   5508             return OMX_ErrorInsufficientResources;
   5509         }
   5510         drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
   5511                 drv_ctx.extradata_info.size,
   5512                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5513                 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
   5514         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
   5515             DEBUG_PRINT_ERROR("Failed to map extradata memory");
   5516             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5517             free_ion_memory(&drv_ctx.extradata_info.ion);
   5518             return OMX_ErrorInsufficientResources;
   5519         }
   5520     }
   5521 #endif
   5522     if (!m_other_extradata) {
   5523         m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
   5524         if (!m_other_extradata) {
   5525             DEBUG_PRINT_ERROR("Failed to alloc memory\n");
   5526             return OMX_ErrorInsufficientResources;
   5527         }
   5528     }
   5529     return OMX_ErrorNone;
   5530 }
   5531 
   5532 void omx_vdec::free_extradata()
   5533 {
   5534 #ifdef USE_ION
   5535     if (drv_ctx.extradata_info.uaddr) {
   5536         munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   5537         close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   5538         free_ion_memory(&drv_ctx.extradata_info.ion);
   5539     }
   5540     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
   5541 #endif
   5542     if (m_other_extradata) {
   5543         free(m_other_extradata);
   5544         m_other_extradata = NULL;
   5545     }
   5546 }
   5547 
   5548 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
   5549         OMX_IN OMX_HANDLETYPE            hComp,
   5550         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5551         OMX_IN OMX_U32                   port,
   5552         OMX_IN OMX_PTR                   appData,
   5553         OMX_IN OMX_U32                   bytes,
   5554         OMX_IN OMX_U8*                   buffer)
   5555 {
   5556     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5557     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   5558     unsigned                         i= 0; // Temporary counter
   5559     struct vdec_setbuffer_cmd setbuffers;
   5560     OMX_PTR privateAppData = NULL;
   5561     private_handle_t *handle = NULL;
   5562     OMX_U8 *buff = buffer;
   5563     struct v4l2_buffer buf;
   5564     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5565     int extra_idx = 0;
   5566     (void) hComp;
   5567     (void) port;
   5568 
   5569     if (!m_out_mem_ptr) {
   5570         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
   5571         eRet = allocate_output_headers();
   5572         if (eRet == OMX_ErrorNone)
   5573             eRet = allocate_extradata();
   5574     }
   5575 
   5576     if (eRet == OMX_ErrorNone) {
   5577         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   5578             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   5579                 break;
   5580             }
   5581         }
   5582     }
   5583 
   5584     if (i >= drv_ctx.op_buf.actualcount) {
   5585         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
   5586         eRet = OMX_ErrorInsufficientResources;
   5587     }
   5588 
   5589     if (eRet != OMX_ErrorNone)
   5590        return eRet;
   5591 
   5592     if (dynamic_buf_mode) {
   5593         *bufferHdr = (m_out_mem_ptr + i );
   5594         (*bufferHdr)->pBuffer = NULL;
   5595         if (i == (drv_ctx.op_buf.actualcount - 1) && !streaming[CAPTURE_PORT]) {
   5596             enum v4l2_buf_type buf_type;
   5597             int rr = 0;
   5598             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5599             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON, &buf_type)) {
   5600                 DEBUG_PRINT_ERROR("STREAMON FAILED : %d", rr);
   5601                 return OMX_ErrorInsufficientResources;
   5602             } else {
   5603                 streaming[CAPTURE_PORT] = true;
   5604                 DEBUG_PRINT_LOW("STREAMON Successful");
   5605             }
   5606 
   5607             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   5608             request_perf_level(VIDC_TURBO);
   5609         }
   5610         BITMASK_SET(&m_out_bm_count,i);
   5611         (*bufferHdr)->pAppPrivate = appData;
   5612         (*bufferHdr)->pBuffer = buffer;
   5613         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   5614         return eRet;
   5615     }
   5616 
   5617     if (eRet == OMX_ErrorNone) {
   5618 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   5619         if (m_enable_android_native_buffers) {
   5620             if (m_use_android_native_buffers) {
   5621                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   5622                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   5623                 handle = (private_handle_t *)nBuf->handle;
   5624                 privateAppData = params->pAppPrivate;
   5625             } else {
   5626                 handle = (private_handle_t *)buff;
   5627                 privateAppData = appData;
   5628             }
   5629             if (!handle) {
   5630                 DEBUG_PRINT_ERROR("handle is invalid");
   5631                 return OMX_ErrorBadParameter;
   5632             }
   5633 
   5634             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   5635                 if (secure_mode && secure_scaling_to_non_secure_opb) {
   5636                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
   5637                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   5638                 } else {
   5639                     DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   5640                             " expected %u, got %u",
   5641                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   5642                     return OMX_ErrorBadParameter;
   5643                 }
   5644             }
   5645 
   5646             drv_ctx.op_buf.buffer_size = handle->size;
   5647 
   5648             if (!m_use_android_native_buffers) {
   5649                 if (!secure_mode) {
   5650                     buff =  (OMX_U8*)mmap(0, handle->size,
   5651                             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   5652                     if (buff == MAP_FAILED) {
   5653                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   5654                         return OMX_ErrorInsufficientResources;
   5655                     }
   5656                 }
   5657             }
   5658 #if defined(_ANDROID_ICS_)
   5659             native_buffer[i].nativehandle = handle;
   5660             native_buffer[i].privatehandle = handle;
   5661 #endif
   5662             if (!handle) {
   5663                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   5664                 return OMX_ErrorBadParameter;
   5665             }
   5666             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   5667             drv_ctx.ptr_outputbuffer[i].offset = 0;
   5668             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   5669             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   5670             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   5671         } else
   5672 #endif
   5673 
   5674             if (!ouput_egl_buffers && !m_use_output_pmem) {
   5675 #ifdef USE_ION
   5676                 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   5677                         drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   5678                         &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   5679                         &drv_ctx.op_buf_ion_info[i].fd_ion_data,
   5680                         secure_mode ? SECURE_FLAGS_OUTPUT_BUFFER : 0);
   5681                 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   5682                     DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   5683                     return OMX_ErrorInsufficientResources;
   5684                 }
   5685                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5686                                       drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   5687 #else
   5688                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5689                                       open (MEM_DEVICE,O_RDWR);
   5690 
   5691                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   5692                     DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5693                     return OMX_ErrorInsufficientResources;
   5694                 }
   5695 
   5696                 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
   5697                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
   5698                     drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   5699                                           open (MEM_DEVICE,O_RDWR);
   5700                     if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   5701                         DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5702                         return OMX_ErrorInsufficientResources;
   5703                     }
   5704                 }
   5705 
   5706                 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   5707                             drv_ctx.op_buf.buffer_size,
   5708                             drv_ctx.op_buf.alignment)) {
   5709                     DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   5710                     close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5711                     return OMX_ErrorInsufficientResources;
   5712                 }
   5713 #endif
   5714                 if (!secure_mode) {
   5715                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
   5716                         (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   5717                                 PROT_READ|PROT_WRITE, MAP_SHARED,
   5718                                 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   5719                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   5720                         close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   5721 #ifdef USE_ION
   5722                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   5723 #endif
   5724                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
   5725                         return OMX_ErrorInsufficientResources;
   5726                     }
   5727                 }
   5728                 drv_ctx.ptr_outputbuffer[i].offset = 0;
   5729                 privateAppData = appData;
   5730             } else {
   5731 
   5732                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   5733                 if (!appData || !bytes ) {
   5734                     if (!secure_mode && !buffer) {
   5735                         DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
   5736                         return OMX_ErrorBadParameter;
   5737                     }
   5738                 }
   5739 
   5740                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   5741                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   5742                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   5743                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
   5744                         !pmem_list->nEntries ||
   5745                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   5746                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
   5747                     return OMX_ErrorBadParameter;
   5748                 }
   5749                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   5750                     pmem_list->entryList->entry;
   5751                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   5752                         pmem_info->pmem_fd);
   5753                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   5754                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   5755                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   5756                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
   5757                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   5758                 privateAppData = appData;
   5759             }
   5760         m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   5761         m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   5762         m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   5763         m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   5764         m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   5765 
   5766         *bufferHdr = (m_out_mem_ptr + i );
   5767         if (secure_mode)
   5768             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   5769         //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   5770         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   5771                 sizeof (vdec_bufferpayload));
   5772 
   5773         DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   5774                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   5775                 drv_ctx.ptr_outputbuffer[i].pmem_fd );
   5776 
   5777         buf.index = i;
   5778         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5779         buf.memory = V4L2_MEMORY_USERPTR;
   5780         plane[0].length = drv_ctx.op_buf.buffer_size;
   5781         plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   5782             (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   5783         plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   5784         plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   5785         plane[0].data_offset = 0;
   5786         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   5787         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   5788             plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   5789             plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   5790 #ifdef USE_ION
   5791             plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   5792 #endif
   5793             plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   5794             plane[extra_idx].data_offset = 0;
   5795         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   5796             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   5797             return OMX_ErrorBadParameter;
   5798         }
   5799         buf.m.planes = plane;
   5800         buf.length = drv_ctx.num_planes;
   5801 
   5802         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
   5803             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   5804             /*TODO: How to handle this case */
   5805             return OMX_ErrorInsufficientResources;
   5806         }
   5807 
   5808         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   5809             enum v4l2_buf_type buf_type;
   5810             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5811             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   5812                 return OMX_ErrorInsufficientResources;
   5813             } else {
   5814                 streaming[CAPTURE_PORT] = true;
   5815                 DEBUG_PRINT_LOW("STREAMON Successful");
   5816             }
   5817 
   5818             DEBUG_PRINT_HIGH("Enabling Turbo mode");
   5819             request_perf_level(VIDC_TURBO);
   5820         }
   5821 
   5822         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   5823         if (m_enable_android_native_buffers) {
   5824             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   5825             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   5826         } else {
   5827             (*bufferHdr)->pBuffer = buff;
   5828         }
   5829         (*bufferHdr)->pAppPrivate = privateAppData;
   5830         BITMASK_SET(&m_out_bm_count,i);
   5831     }
   5832     return eRet;
   5833 }
   5834 
   5835 /* ======================================================================
   5836    FUNCTION
   5837    omx_vdec::use_input_heap_buffers
   5838 
   5839    DESCRIPTION
   5840    OMX Use Buffer Heap allocation method implementation.
   5841 
   5842    PARAMETERS
   5843    <TBD>.
   5844 
   5845    RETURN VALUE
   5846    OMX Error None , if everything successful.
   5847 
   5848    ========================================================================== */
   5849 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
   5850         OMX_IN OMX_HANDLETYPE            hComp,
   5851         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5852         OMX_IN OMX_U32                   port,
   5853         OMX_IN OMX_PTR                   appData,
   5854         OMX_IN OMX_U32                   bytes,
   5855         OMX_IN OMX_U8*                   buffer)
   5856 {
   5857     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
   5858     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5859 
   5860     if (secure_mode) {
   5861         DEBUG_PRINT_ERROR("use_input_heap_buffers is not allowed in secure mode");
   5862         return OMX_ErrorUndefined;
   5863     }
   5864 
   5865     if (!m_inp_heap_ptr)
   5866         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   5867             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   5868                     drv_ctx.ip_buf.actualcount);
   5869     if (!m_phdr_pmem_ptr)
   5870         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   5871             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   5872                     drv_ctx.ip_buf.actualcount);
   5873     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
   5874         DEBUG_PRINT_ERROR("Insufficent memory");
   5875         eRet = OMX_ErrorInsufficientResources;
   5876     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
   5877         input_use_buffer = true;
   5878         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   5879         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   5880         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   5881         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   5882         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   5883         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   5884         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   5885         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   5886         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   5887         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
   5888                     (unsigned)NULL, (unsigned)NULL)) {
   5889             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   5890             return OMX_ErrorInsufficientResources;
   5891         }
   5892         m_in_alloc_cnt++;
   5893     } else {
   5894         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
   5895         eRet = OMX_ErrorInsufficientResources;
   5896     }
   5897     return eRet;
   5898 }
   5899 
   5900 /* ======================================================================
   5901    FUNCTION
   5902    omx_vdec::UseBuffer
   5903 
   5904    DESCRIPTION
   5905    OMX Use Buffer method implementation.
   5906 
   5907    PARAMETERS
   5908    <TBD>.
   5909 
   5910    RETURN VALUE
   5911    OMX Error None , if everything successful.
   5912 
   5913    ========================================================================== */
   5914 OMX_ERRORTYPE  omx_vdec::use_buffer(
   5915         OMX_IN OMX_HANDLETYPE            hComp,
   5916         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5917         OMX_IN OMX_U32                   port,
   5918         OMX_IN OMX_PTR                   appData,
   5919         OMX_IN OMX_U32                   bytes,
   5920         OMX_IN OMX_U8*                   buffer)
   5921 {
   5922     OMX_ERRORTYPE error = OMX_ErrorNone;
   5923     struct vdec_setbuffer_cmd setbuffers;
   5924 
   5925     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
   5926             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
   5927             return OMX_ErrorBadParameter;
   5928     }
   5929     if (m_state == OMX_StateInvalid) {
   5930         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
   5931         return OMX_ErrorInvalidState;
   5932     }
   5933     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   5934         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
   5935         // ensure that use-buffer was called for previous allocation.
   5936         // Mix-and-match of useBuffer and allocateBuffer is not allowed
   5937         if (m_inp_mem_ptr && !input_use_buffer) {
   5938             DEBUG_PRINT_ERROR("'Use' Input buffer called after 'Allocate' Input buffer !");
   5939             return OMX_ErrorUndefined;
   5940         }
   5941         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   5942     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
   5943         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
   5944     else {
   5945         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   5946         error = OMX_ErrorBadPortIndex;
   5947     }
   5948     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
   5949     if (error == OMX_ErrorNone) {
   5950         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   5951             // Send the callback now
   5952             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   5953             post_event(OMX_CommandStateSet,OMX_StateIdle,
   5954                     OMX_COMPONENT_GENERATE_EVENT);
   5955         }
   5956         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   5957                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   5958             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5959             post_event(OMX_CommandPortEnable,
   5960                     OMX_CORE_INPUT_PORT_INDEX,
   5961                     OMX_COMPONENT_GENERATE_EVENT);
   5962         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   5963                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   5964             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5965             post_event(OMX_CommandPortEnable,
   5966                     OMX_CORE_OUTPUT_PORT_INDEX,
   5967                     OMX_COMPONENT_GENERATE_EVENT);
   5968         }
   5969     }
   5970     return error;
   5971 }
   5972 
   5973 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
   5974         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
   5975 {
   5976     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
   5977         if (m_inp_heap_ptr[bufferindex].pBuffer)
   5978             free(m_inp_heap_ptr[bufferindex].pBuffer);
   5979         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
   5980     }
   5981     if (pmem_bufferHdr)
   5982         free_input_buffer(pmem_bufferHdr);
   5983     return OMX_ErrorNone;
   5984 }
   5985 
   5986 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   5987 {
   5988     unsigned int index = 0;
   5989     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   5990         return OMX_ErrorBadParameter;
   5991     }
   5992 
   5993     index = bufferHdr - m_inp_mem_ptr;
   5994     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   5995 
   5996     auto_lock l(buf_lock);
   5997     bufferHdr->pInputPortPrivate = NULL;
   5998 
   5999     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   6000         DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   6001         if (drv_ctx.ptr_inputbuffer[index].pmem_fd >= 0) {
   6002             struct vdec_setbuffer_cmd setbuffers;
   6003             setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   6004             memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   6005                     sizeof (vdec_bufferpayload));
   6006             if (!secure_mode) {
   6007                 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
   6008                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
   6009                 DEBUG_PRINT_LOW("unmap the input buffer size=%u  address = %p",
   6010                         (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size,
   6011                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
   6012                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   6013                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
   6014                 close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
   6015             } else if (allocate_native_handle){
   6016                 native_handle_t *nh = (native_handle_t *)bufferHdr->pBuffer;
   6017                 native_handle_close(nh);
   6018                 native_handle_delete(nh);
   6019             }
   6020             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   6021             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
   6022                 free(m_desc_buffer_ptr[index].buf_addr);
   6023                 m_desc_buffer_ptr[index].buf_addr = NULL;
   6024                 m_desc_buffer_ptr[index].desc_data_size = 0;
   6025             }
   6026 #ifdef USE_ION
   6027             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   6028 #endif
   6029         }
   6030     }
   6031 
   6032     return OMX_ErrorNone;
   6033 }
   6034 
   6035 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   6036 {
   6037     unsigned int index = 0;
   6038 
   6039     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   6040         return OMX_ErrorBadParameter;
   6041     }
   6042 
   6043     index = bufferHdr - m_out_mem_ptr;
   6044     DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
   6045 
   6046     if (index < drv_ctx.op_buf.actualcount
   6047             && drv_ctx.ptr_outputbuffer) {
   6048         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
   6049                 drv_ctx.ptr_outputbuffer[index].bufferaddr);
   6050 
   6051         struct vdec_setbuffer_cmd setbuffers;
   6052         setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   6053         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   6054                 sizeof (vdec_bufferpayload));
   6055 
   6056         if (!dynamic_buf_mode) {
   6057             if (streaming[CAPTURE_PORT] &&
   6058                 !(in_reconfig || BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING))) {
   6059                 if (stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   6060                     DEBUG_PRINT_ERROR("STREAMOFF Failed");
   6061                 } else {
   6062                     DEBUG_PRINT_LOW("STREAMOFF Successful");
   6063                 }
   6064             }
   6065 #ifdef _ANDROID_
   6066             if (m_enable_android_native_buffers) {
   6067                 if (!secure_mode) {
   6068                     if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   6069                         munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   6070                                 drv_ctx.ptr_outputbuffer[index].mmaped_size);
   6071                     }
   6072                 }
   6073                 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   6074             } else {
   6075 #endif
   6076                 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
   6077                     if (!secure_mode) {
   6078                         DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
   6079                                 drv_ctx.ptr_outputbuffer[0].pmem_fd);
   6080                         DEBUG_PRINT_LOW("unmap the ouput buffer size=%u  address = %p",
   6081                                 (unsigned int)drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
   6082                                 drv_ctx.ptr_outputbuffer[0].bufferaddr);
   6083                         munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
   6084                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
   6085                     }
   6086                     close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
   6087                     drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
   6088 #ifdef USE_ION
   6089                     free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
   6090 #endif
   6091                 }
   6092 #ifdef _ANDROID_
   6093             }
   6094 #endif
   6095         } //!dynamic_buf_mode
   6096         if (release_output_done()) {
   6097             free_extradata();
   6098         }
   6099     }
   6100 
   6101     return OMX_ErrorNone;
   6102 
   6103 }
   6104 
   6105 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   6106         OMX_BUFFERHEADERTYPE **bufferHdr,
   6107         OMX_U32              port,
   6108         OMX_PTR              appData,
   6109         OMX_U32              bytes)
   6110 {
   6111     OMX_BUFFERHEADERTYPE *input = NULL;
   6112     unsigned char *buf_addr = NULL;
   6113     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6114     unsigned   i = 0;
   6115 
   6116     /* Sanity Check*/
   6117     if (bufferHdr == NULL) {
   6118         return OMX_ErrorBadParameter;
   6119     }
   6120 
   6121     if (m_inp_heap_ptr == NULL) {
   6122         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   6123                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   6124                          drv_ctx.ip_buf.actualcount);
   6125         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   6126                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   6127                           drv_ctx.ip_buf.actualcount);
   6128 
   6129         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
   6130             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
   6131             return OMX_ErrorInsufficientResources;
   6132         }
   6133     }
   6134 
   6135     /*Find a Free index*/
   6136     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6137         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
   6138             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6139             break;
   6140         }
   6141     }
   6142 
   6143     if (i < drv_ctx.ip_buf.actualcount) {
   6144         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   6145 
   6146         if (buf_addr == NULL) {
   6147             return OMX_ErrorInsufficientResources;
   6148         }
   6149 
   6150         *bufferHdr = (m_inp_heap_ptr + i);
   6151         input = *bufferHdr;
   6152         BITMASK_SET(&m_heap_inp_bm_count,i);
   6153 
   6154         input->pBuffer           = (OMX_U8 *)buf_addr;
   6155         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6156         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6157         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6158         input->pAppPrivate       = appData;
   6159         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6160         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
   6161         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   6162         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   6163         /*Add the Buffers to freeq*/
   6164         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
   6165                     (unsigned)NULL, (unsigned)NULL)) {
   6166             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   6167             return OMX_ErrorInsufficientResources;
   6168         }
   6169     } else {
   6170         return OMX_ErrorBadParameter;
   6171     }
   6172 
   6173     return eRet;
   6174 
   6175 }
   6176 
   6177 
   6178 /* ======================================================================
   6179    FUNCTION
   6180    omx_vdec::AllocateInputBuffer
   6181 
   6182    DESCRIPTION
   6183    Helper function for allocate buffer in the input pin
   6184 
   6185    PARAMETERS
   6186    None.
   6187 
   6188    RETURN VALUE
   6189    true/false
   6190 
   6191    ========================================================================== */
   6192 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   6193         OMX_IN OMX_HANDLETYPE            hComp,
   6194         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6195         OMX_IN OMX_U32                   port,
   6196         OMX_IN OMX_PTR                   appData,
   6197         OMX_IN OMX_U32                   bytes)
   6198 {
   6199     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6200     struct vdec_setbuffer_cmd setbuffers;
   6201     OMX_BUFFERHEADERTYPE *input = NULL;
   6202     unsigned   i = 0;
   6203     unsigned char *buf_addr = NULL;
   6204     int pmem_fd = -1, ret = 0;
   6205 
   6206     (void) hComp;
   6207     (void) port;
   6208 
   6209 
   6210     if (bytes != drv_ctx.ip_buf.buffer_size) {
   6211         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
   6212                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
   6213         return OMX_ErrorBadParameter;
   6214     }
   6215 
   6216     if (!m_inp_mem_ptr) {
   6217         struct v4l2_requestbuffers bufreq;
   6218         bufreq.memory = V4L2_MEMORY_USERPTR;
   6219         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6220         bufreq.count = drv_ctx.ip_buf.actualcount;
   6221         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   6222         if (ret) {
   6223             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %s", strerror(errno));
   6224             /*TODO: How to handle this case */
   6225             eRet = OMX_ErrorInsufficientResources;
   6226         } else if (bufreq.count != drv_ctx.ip_buf.actualcount) {
   6227             DEBUG_PRINT_ERROR("%s Count(%d) is not expected to change to %d",
   6228                 __FUNCTION__, drv_ctx.ip_buf.actualcount, bufreq.count);
   6229             eRet = OMX_ErrorInsufficientResources;
   6230         }
   6231 
   6232         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
   6233                 drv_ctx.ip_buf.actualcount,
   6234                 (unsigned int)drv_ctx.ip_buf.buffer_size);
   6235 
   6236         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   6237                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   6238 
   6239         if (m_inp_mem_ptr == NULL) {
   6240             return OMX_ErrorInsufficientResources;
   6241         }
   6242 
   6243         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   6244                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   6245 
   6246         if (drv_ctx.ptr_inputbuffer == NULL) {
   6247             return OMX_ErrorInsufficientResources;
   6248         }
   6249 #ifdef USE_ION
   6250         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   6251                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   6252 
   6253         if (drv_ctx.ip_buf_ion_info == NULL) {
   6254             return OMX_ErrorInsufficientResources;
   6255         }
   6256 #endif
   6257 
   6258         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   6259             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   6260 #ifdef USE_ION
   6261             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   6262 #endif
   6263         }
   6264     }
   6265 
   6266     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   6267         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6268             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   6269             break;
   6270         }
   6271     }
   6272 
   6273     if (i < drv_ctx.ip_buf.actualcount) {
   6274         struct v4l2_buffer buf;
   6275         struct v4l2_plane plane;
   6276         int rc;
   6277         DEBUG_PRINT_LOW("Allocate input Buffer");
   6278 #ifdef USE_ION
   6279         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   6280                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   6281                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   6282                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ?
   6283                 SECURE_FLAGS_INPUT_BUFFER : ION_FLAG_CACHED);
   6284         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   6285             return OMX_ErrorInsufficientResources;
   6286         }
   6287         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   6288 #else
   6289         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6290 
   6291         if (pmem_fd < 0) {
   6292             DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6293             return OMX_ErrorInsufficientResources;
   6294         }
   6295 
   6296         if (pmem_fd == 0) {
   6297             pmem_fd = open (MEM_DEVICE,O_RDWR);
   6298 
   6299             if (pmem_fd < 0) {
   6300                 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   6301                 return OMX_ErrorInsufficientResources;
   6302             }
   6303         }
   6304 
   6305         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   6306                     drv_ctx.ip_buf.alignment)) {
   6307             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6308             close(pmem_fd);
   6309             return OMX_ErrorInsufficientResources;
   6310         }
   6311 #endif
   6312         if (!secure_mode) {
   6313             buf_addr = (unsigned char *)mmap(NULL,
   6314                     drv_ctx.ip_buf.buffer_size,
   6315                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   6316 
   6317             if (buf_addr == MAP_FAILED) {
   6318                 close(pmem_fd);
   6319 #ifdef USE_ION
   6320                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   6321 #endif
   6322                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
   6323                 return OMX_ErrorInsufficientResources;
   6324             }
   6325         }
   6326         *bufferHdr = (m_inp_mem_ptr + i);
   6327         if (secure_mode)
   6328             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   6329         else
   6330             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   6331         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   6332         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   6333         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   6334         drv_ctx.ptr_inputbuffer [i].offset = 0;
   6335 
   6336 
   6337         buf.index = i;
   6338         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6339         buf.memory = V4L2_MEMORY_USERPTR;
   6340         plane.bytesused = 0;
   6341         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   6342         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   6343         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   6344         plane.reserved[1] = 0;
   6345         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   6346         buf.m.planes = &plane;
   6347         buf.length = 1;
   6348 
   6349         DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
   6350                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   6351 
   6352         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6353 
   6354         if (rc) {
   6355             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   6356             /*TODO: How to handle this case */
   6357             return OMX_ErrorInsufficientResources;
   6358         }
   6359 
   6360         input = *bufferHdr;
   6361         BITMASK_SET(&m_inp_bm_count,i);
   6362         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
   6363         if (allocate_native_handle) {
   6364             native_handle_t *nh = native_handle_create(1 /*numFds*/, 0 /*numInts*/);
   6365             nh->data[0] = drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6366             input->pBuffer = (OMX_U8 *)nh;
   6367         } else if (secure_mode || m_input_pass_buffer_fd) {
   6368             /*Legacy method, pass ion fd stashed directly in pBuffer*/
   6369             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer[i].pmem_fd;
   6370         } else {
   6371             input->pBuffer           = (OMX_U8 *)buf_addr;
   6372         }
   6373         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   6374         input->nVersion.nVersion = OMX_SPEC_VERSION;
   6375         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   6376         input->pAppPrivate       = appData;
   6377         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   6378         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   6379 
   6380         if (drv_ctx.disable_dmx) {
   6381             eRet = allocate_desc_buffer(i);
   6382         }
   6383     } else {
   6384         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   6385         eRet = OMX_ErrorInsufficientResources;
   6386     }
   6387     return eRet;
   6388 }
   6389 
   6390 
   6391 /* ======================================================================
   6392    FUNCTION
   6393    omx_vdec::AllocateOutputBuffer
   6394 
   6395    DESCRIPTION
   6396    Helper fn for AllocateBuffer in the output pin
   6397 
   6398    PARAMETERS
   6399    <TBD>.
   6400 
   6401    RETURN VALUE
   6402    OMX Error None if everything went well.
   6403 
   6404    ========================================================================== */
   6405 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   6406         OMX_IN OMX_HANDLETYPE            hComp,
   6407         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6408         OMX_IN OMX_U32                   port,
   6409         OMX_IN OMX_PTR                   appData,
   6410         OMX_IN OMX_U32                   bytes)
   6411 {
   6412     (void)hComp;
   6413     (void)port;
   6414     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6415     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   6416     unsigned                         i= 0; // Temporary counter
   6417     struct vdec_setbuffer_cmd setbuffers;
   6418     int extra_idx = 0;
   6419 #ifdef USE_ION
   6420     int ion_device_fd =-1;
   6421     struct ion_allocation_data ion_alloc_data;
   6422     struct ion_fd_data fd_ion_data;
   6423 #endif
   6424     if (!m_out_mem_ptr) {
   6425         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
   6426                 drv_ctx.op_buf.actualcount,
   6427                 (unsigned int)drv_ctx.op_buf.buffer_size);
   6428         int nBufHdrSize        = 0;
   6429         int nPlatformEntrySize = 0;
   6430         int nPlatformListSize  = 0;
   6431         int nPMEMInfoSize = 0;
   6432         int pmem_fd = -1;
   6433         unsigned char *pmem_baseaddress = NULL;
   6434 
   6435         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   6436         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   6437         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   6438 
   6439         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
   6440                 drv_ctx.op_buf.actualcount);
   6441         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   6442             sizeof(OMX_BUFFERHEADERTYPE);
   6443 
   6444         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   6445             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   6446         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   6447             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   6448         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   6449             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   6450 
   6451         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   6452                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   6453                 nPMEMInfoSize,
   6454                 nPlatformListSize);
   6455         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
   6456                 drv_ctx.op_buf.actualcount);
   6457 #ifdef USE_ION
   6458         // Allocate output buffers as cached to improve performance of software-reading
   6459         // of the YUVs. Output buffers are cache-invalidated in driver.
   6460         // If color-conversion is involved, Only the C2D output buffers are cached, no
   6461         // need to cache the decoder's output buffers
   6462         int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
   6463         ion_device_fd = alloc_map_ion_memory(
   6464                 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
   6465                 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
   6466                 &ion_alloc_data, &fd_ion_data,
   6467                 (secure_mode && !secure_scaling_to_non_secure_opb) ?
   6468                 SECURE_FLAGS_OUTPUT_BUFFER : cache_flag);
   6469         if (ion_device_fd < 0) {
   6470             return OMX_ErrorInsufficientResources;
   6471         }
   6472         pmem_fd = fd_ion_data.fd;
   6473 #else
   6474         pmem_fd = open (MEM_DEVICE,O_RDWR);
   6475 
   6476         if (pmem_fd < 0) {
   6477             DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   6478                     drv_ctx.op_buf.buffer_size);
   6479             return OMX_ErrorInsufficientResources;
   6480         }
   6481 
   6482         if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
   6483                     drv_ctx.op_buf.actualcount,
   6484                     drv_ctx.op_buf.alignment)) {
   6485             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   6486             close(pmem_fd);
   6487             return OMX_ErrorInsufficientResources;
   6488         }
   6489 #endif
   6490         if (!secure_mode) {
   6491             pmem_baseaddress = (unsigned char *)mmap(NULL,
   6492                     (drv_ctx.op_buf.buffer_size *
   6493                      drv_ctx.op_buf.actualcount),
   6494                     PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   6495             if (pmem_baseaddress == MAP_FAILED) {
   6496                 DEBUG_PRINT_ERROR("MMAP failed for Size %u",
   6497                         (unsigned int)drv_ctx.op_buf.buffer_size);
   6498                 close(pmem_fd);
   6499 #ifdef USE_ION
   6500                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   6501 #endif
   6502                 return OMX_ErrorInsufficientResources;
   6503             }
   6504         }
   6505         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   6506         // Alloc mem for platform specific info
   6507         char *pPtr=NULL;
   6508         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   6509                 nPMEMInfoSize,1);
   6510         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   6511                        calloc (sizeof(struct vdec_bufferpayload),
   6512                                drv_ctx.op_buf.actualcount);
   6513         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   6514                      calloc (sizeof (struct vdec_output_frameinfo),
   6515                              drv_ctx.op_buf.actualcount);
   6516         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   6517             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
   6518             return OMX_ErrorInsufficientResources;
   6519         }
   6520 
   6521 #ifdef USE_ION
   6522         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   6523                       calloc (sizeof(struct vdec_ion),
   6524                               drv_ctx.op_buf.actualcount);
   6525         if (!drv_ctx.op_buf_ion_info) {
   6526             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   6527             return OMX_ErrorInsufficientResources;
   6528         }
   6529 #endif
   6530 
   6531         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   6532                 && drv_ctx.ptr_respbuffer) {
   6533             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   6534                 (drv_ctx.op_buf.buffer_size *
   6535                  drv_ctx.op_buf.actualcount);
   6536             bufHdr          =  m_out_mem_ptr;
   6537             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   6538             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   6539                 (((char *) m_platform_list)  + nPlatformListSize);
   6540             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   6541                 (((char *) m_platform_entry) + nPlatformEntrySize);
   6542             pPlatformList   = m_platform_list;
   6543             pPlatformEntry  = m_platform_entry;
   6544             pPMEMInfo       = m_pmem_info;
   6545 
   6546             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   6547 
   6548             // Settting the entire storage nicely
   6549             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
   6550             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   6551             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   6552                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   6553                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   6554                 // Set the values when we determine the right HxW param
   6555                 bufHdr->nAllocLen          = bytes;
   6556                 bufHdr->nFilledLen         = 0;
   6557                 bufHdr->pAppPrivate        = appData;
   6558                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   6559                 // Platform specific PMEM Information
   6560                 // Initialize the Platform Entry
   6561                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
   6562                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   6563                 pPlatformEntry->entry      = pPMEMInfo;
   6564                 // Initialize the Platform List
   6565                 pPlatformList->nEntries    = 1;
   6566                 pPlatformList->entryList   = pPlatformEntry;
   6567                 // Keep pBuffer NULL till vdec is opened
   6568                 bufHdr->pBuffer            = NULL;
   6569                 bufHdr->nOffset            = 0;
   6570 
   6571                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   6572                 pPMEMInfo->pmem_fd = -1;
   6573                 bufHdr->pPlatformPrivate = pPlatformList;
   6574 
   6575                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   6576                 m_pmem_info[i].pmem_fd = pmem_fd;
   6577 #ifdef USE_ION
   6578                 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
   6579                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
   6580                 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
   6581 #endif
   6582 
   6583                 /*Create a mapping between buffers*/
   6584                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   6585                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   6586                                     &drv_ctx.ptr_outputbuffer[i];
   6587                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
   6588                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   6589                     pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
   6590                 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   6591                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   6592                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   6593 
   6594                 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
   6595                         pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
   6596                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   6597                 // Move the buffer and buffer header pointers
   6598                 bufHdr++;
   6599                 pPMEMInfo++;
   6600                 pPlatformEntry++;
   6601                 pPlatformList++;
   6602             }
   6603         } else {
   6604             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   6605                     m_out_mem_ptr, pPtr);
   6606             if (m_out_mem_ptr) {
   6607                 free(m_out_mem_ptr);
   6608                 m_out_mem_ptr = NULL;
   6609             }
   6610             if (pPtr) {
   6611                 free(pPtr);
   6612                 pPtr = NULL;
   6613             }
   6614             if (drv_ctx.ptr_outputbuffer) {
   6615                 free(drv_ctx.ptr_outputbuffer);
   6616                 drv_ctx.ptr_outputbuffer = NULL;
   6617             }
   6618             if (drv_ctx.ptr_respbuffer) {
   6619                 free(drv_ctx.ptr_respbuffer);
   6620                 drv_ctx.ptr_respbuffer = NULL;
   6621             }
   6622 #ifdef USE_ION
   6623             if (drv_ctx.op_buf_ion_info) {
   6624                 DEBUG_PRINT_LOW("Free o/p ion context");
   6625                 free(drv_ctx.op_buf_ion_info);
   6626                 drv_ctx.op_buf_ion_info = NULL;
   6627             }
   6628 #endif
   6629             eRet =  OMX_ErrorInsufficientResources;
   6630         }
   6631         if (eRet == OMX_ErrorNone)
   6632             eRet = allocate_extradata();
   6633     }
   6634 
   6635     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   6636         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   6637             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   6638             break;
   6639         }
   6640     }
   6641 
   6642     if (eRet == OMX_ErrorNone) {
   6643         if (i < drv_ctx.op_buf.actualcount) {
   6644             struct v4l2_buffer buf;
   6645             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   6646             int rc;
   6647             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   6648 
   6649             drv_ctx.ptr_outputbuffer[i].buffer_len =
   6650                 drv_ctx.op_buf.buffer_size;
   6651 
   6652             *bufferHdr = (m_out_mem_ptr + i );
   6653             if (secure_mode) {
   6654 #ifdef USE_ION
   6655                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   6656                     (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   6657 #else
   6658                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   6659 #endif
   6660             }
   6661             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   6662 
   6663             buf.index = i;
   6664             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6665             buf.memory = V4L2_MEMORY_USERPTR;
   6666             plane[0].length = drv_ctx.op_buf.buffer_size;
   6667             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   6668                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   6669 #ifdef USE_ION
   6670             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   6671 #endif
   6672             plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   6673             plane[0].data_offset = 0;
   6674             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   6675             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   6676                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   6677                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   6678 #ifdef USE_ION
   6679                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   6680 #endif
   6681                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   6682                 plane[extra_idx].data_offset = 0;
   6683             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   6684                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
   6685                 return OMX_ErrorBadParameter;
   6686             }
   6687             buf.m.planes = plane;
   6688             buf.length = drv_ctx.num_planes;
   6689             DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   6690             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   6691             if (rc) {
   6692                 /*TODO: How to handle this case */
   6693                 return OMX_ErrorInsufficientResources;
   6694             }
   6695 
   6696             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   6697                 enum v4l2_buf_type buf_type;
   6698                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6699                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   6700                 if (rc) {
   6701                     return OMX_ErrorInsufficientResources;
   6702                 } else {
   6703                     streaming[CAPTURE_PORT] = true;
   6704                     DEBUG_PRINT_LOW("STREAMON Successful");
   6705                 }
   6706 
   6707                 DEBUG_PRINT_HIGH("Enabling Turbo mode");
   6708                 request_perf_level(VIDC_TURBO);
   6709             }
   6710 
   6711             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   6712             (*bufferHdr)->pAppPrivate = appData;
   6713             BITMASK_SET(&m_out_bm_count,i);
   6714         } else {
   6715             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
   6716             eRet = OMX_ErrorInsufficientResources;
   6717         }
   6718     }
   6719 
   6720     return eRet;
   6721 }
   6722 
   6723 
   6724 // AllocateBuffer  -- API Call
   6725 /* ======================================================================
   6726    FUNCTION
   6727    omx_vdec::AllocateBuffer
   6728 
   6729    DESCRIPTION
   6730    Returns zero if all the buffers released..
   6731 
   6732    PARAMETERS
   6733    None.
   6734 
   6735    RETURN VALUE
   6736    true/false
   6737 
   6738    ========================================================================== */
   6739 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   6740         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6741         OMX_IN OMX_U32                        port,
   6742         OMX_IN OMX_PTR                     appData,
   6743         OMX_IN OMX_U32                       bytes)
   6744 {
   6745     unsigned i = 0;
   6746     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   6747 
   6748     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
   6749     if (m_state == OMX_StateInvalid) {
   6750         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
   6751         return OMX_ErrorInvalidState;
   6752     }
   6753 
   6754     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6755         // If this is not the first allocation (i.e m_inp_mem_ptr is allocated),
   6756         // ensure that use-buffer was never called.
   6757         // Mix-and-match of useBuffer and allocateBuffer is not allowed
   6758         if (m_inp_mem_ptr && input_use_buffer) {
   6759             DEBUG_PRINT_ERROR("'Allocate' Input buffer called after 'Use' Input buffer !");
   6760             return OMX_ErrorUndefined;
   6761         }
   6762         if (arbitrary_bytes) {
   6763             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   6764         } else {
   6765             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   6766         }
   6767     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6768         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   6769                 appData,bytes);
   6770     } else {
   6771         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   6772         eRet = OMX_ErrorBadPortIndex;
   6773     }
   6774     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   6775     if (eRet == OMX_ErrorNone) {
   6776         if (allocate_done()) {
   6777             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   6778                 // Send the callback now
   6779                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   6780                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   6781                         OMX_COMPONENT_GENERATE_EVENT);
   6782             }
   6783         }
   6784         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   6785             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   6786                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   6787                 post_event(OMX_CommandPortEnable,
   6788                         OMX_CORE_INPUT_PORT_INDEX,
   6789                         OMX_COMPONENT_GENERATE_EVENT);
   6790             }
   6791         }
   6792         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   6793             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   6794                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   6795                 post_event(OMX_CommandPortEnable,
   6796                         OMX_CORE_OUTPUT_PORT_INDEX,
   6797                         OMX_COMPONENT_GENERATE_EVENT);
   6798             }
   6799         }
   6800     }
   6801     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   6802     return eRet;
   6803 }
   6804 
   6805 // Free Buffer - API call
   6806 /* ======================================================================
   6807    FUNCTION
   6808    omx_vdec::FreeBuffer
   6809 
   6810    DESCRIPTION
   6811 
   6812    PARAMETERS
   6813    None.
   6814 
   6815    RETURN VALUE
   6816    true/false
   6817 
   6818    ========================================================================== */
   6819 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   6820         OMX_IN OMX_U32                 port,
   6821         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6822 {
   6823     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6824     unsigned int nPortIndex;
   6825     (void) hComp;
   6826     DEBUG_PRINT_LOW("In for decoder free_buffer");
   6827 
   6828     if (m_state == OMX_StateIdle &&
   6829             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   6830         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   6831     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   6832             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   6833         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   6834     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   6835                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   6836             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   6837              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   6838         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
   6839     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   6840         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
   6841         post_event(OMX_EventError,
   6842                 OMX_ErrorPortUnpopulated,
   6843                 OMX_COMPONENT_GENERATE_EVENT);
   6844 
   6845         return OMX_ErrorIncorrectStateOperation;
   6846     } else if (m_state != OMX_StateInvalid) {
   6847         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
   6848         post_event(OMX_EventError,
   6849                 OMX_ErrorPortUnpopulated,
   6850                 OMX_COMPONENT_GENERATE_EVENT);
   6851     }
   6852 
   6853     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   6854         /*Check if arbitrary bytes*/
   6855         if (!arbitrary_bytes && !input_use_buffer)
   6856             nPortIndex = buffer - m_inp_mem_ptr;
   6857         else
   6858             nPortIndex = buffer - m_inp_heap_ptr;
   6859 
   6860         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
   6861         if (nPortIndex < drv_ctx.ip_buf.actualcount &&
   6862                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
   6863             // Clear the bit associated with it.
   6864             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   6865             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   6866             if (input_use_buffer == true) {
   6867 
   6868                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
   6869                 if (m_phdr_pmem_ptr)
   6870                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   6871             } else {
   6872                 if (arbitrary_bytes) {
   6873                     if (m_phdr_pmem_ptr)
   6874                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   6875                     else
   6876                         free_input_buffer(nPortIndex,NULL);
   6877                 } else
   6878                     free_input_buffer(buffer);
   6879             }
   6880             m_inp_bPopulated = OMX_FALSE;
   6881             if(release_input_done())
   6882                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   6883             /*Free the Buffer Header*/
   6884             if (release_input_done()) {
   6885                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
   6886                 free_input_buffer_header();
   6887             }
   6888         } else {
   6889             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
   6890             eRet = OMX_ErrorBadPortIndex;
   6891         }
   6892 
   6893         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   6894                 && release_input_done()) {
   6895             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   6896             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   6897             post_event(OMX_CommandPortDisable,
   6898                     OMX_CORE_INPUT_PORT_INDEX,
   6899                     OMX_COMPONENT_GENERATE_EVENT);
   6900         }
   6901     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   6902         // check if the buffer is valid
   6903         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   6904         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   6905                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
   6906             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
   6907             // Clear the bit associated with it.
   6908             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   6909             m_out_bPopulated = OMX_FALSE;
   6910             client_buffers.free_output_buffer (buffer);
   6911 
   6912             if(release_output_done()) {
   6913                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   6914             }
   6915             if (release_output_done()) {
   6916                 free_output_buffer_header();
   6917             }
   6918         } else {
   6919             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
   6920             eRet = OMX_ErrorBadPortIndex;
   6921         }
   6922         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   6923                 && release_output_done()) {
   6924             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   6925 
   6926             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   6927             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   6928 #ifdef _ANDROID_ICS_
   6929             if (m_enable_android_native_buffers) {
   6930                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   6931                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   6932             }
   6933 #endif
   6934 
   6935             post_event(OMX_CommandPortDisable,
   6936                     OMX_CORE_OUTPUT_PORT_INDEX,
   6937                     OMX_COMPONENT_GENERATE_EVENT);
   6938         }
   6939     } else {
   6940         eRet = OMX_ErrorBadPortIndex;
   6941     }
   6942     if ((eRet == OMX_ErrorNone) &&
   6943             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   6944         if (release_done()) {
   6945             // Send the callback now
   6946             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   6947             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   6948                     OMX_COMPONENT_GENERATE_EVENT);
   6949         }
   6950     }
   6951     return eRet;
   6952 }
   6953 
   6954 
   6955 /* ======================================================================
   6956    FUNCTION
   6957    omx_vdec::EmptyThisBuffer
   6958 
   6959    DESCRIPTION
   6960    This routine is used to push the encoded video frames to
   6961    the video decoder.
   6962 
   6963    PARAMETERS
   6964    None.
   6965 
   6966    RETURN VALUE
   6967    OMX Error None if everything went successful.
   6968 
   6969    ========================================================================== */
   6970 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   6971         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6972 {
   6973     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   6974     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   6975 
   6976     if (m_state != OMX_StateExecuting &&
   6977             m_state != OMX_StatePause &&
   6978             m_state != OMX_StateIdle) {
   6979         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
   6980         return OMX_ErrorInvalidState;
   6981     }
   6982 
   6983     if (buffer == NULL) {
   6984         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   6985         return OMX_ErrorBadParameter;
   6986     }
   6987 
   6988     if (!m_inp_bEnabled) {
   6989         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   6990         return OMX_ErrorIncorrectStateOperation;
   6991     }
   6992 
   6993     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   6994         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
   6995         return OMX_ErrorBadPortIndex;
   6996     }
   6997 
   6998     if (perf_flag) {
   6999         if (!latency) {
   7000             dec_time.stop();
   7001             latency = dec_time.processing_time_us();
   7002             dec_time.start();
   7003         }
   7004     }
   7005 
   7006     if (arbitrary_bytes) {
   7007         nBufferIndex = buffer - m_inp_heap_ptr;
   7008     } else {
   7009         if (input_use_buffer == true) {
   7010             nBufferIndex = buffer - m_inp_heap_ptr;
   7011             if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7012                 DEBUG_PRINT_ERROR("ERROR: ETB nBufferIndex is invalid in use-buffer mode");
   7013                 return OMX_ErrorBadParameter;
   7014             }
   7015             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   7016             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   7017             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   7018             buffer = &m_inp_mem_ptr[nBufferIndex];
   7019             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
   7020                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
   7021         } else {
   7022             nBufferIndex = buffer - m_inp_mem_ptr;
   7023         }
   7024     }
   7025 
   7026     if (nBufferIndex >= drv_ctx.ip_buf.actualcount ) {
   7027         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   7028         return OMX_ErrorBadParameter;
   7029     }
   7030 
   7031     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7032         codec_config_flag = true;
   7033         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   7034     }
   7035 
   7036     /* The client should not set this when codec is in arbitrary bytes mode */
   7037     if (m_input_pass_buffer_fd) {
   7038         buffer->pBuffer = (OMX_U8*)drv_ctx.ptr_inputbuffer[nBufferIndex].bufferaddr;
   7039     }
   7040 
   7041     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
   7042             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
   7043     if (arbitrary_bytes) {
   7044         post_event ((unsigned long)hComp,(unsigned long)buffer,
   7045                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   7046     } else {
   7047         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
   7048     }
   7049     time_stamp_dts.insert_timestamp(buffer);
   7050     return OMX_ErrorNone;
   7051 }
   7052 
   7053 /* ======================================================================
   7054    FUNCTION
   7055    omx_vdec::empty_this_buffer_proxy
   7056 
   7057    DESCRIPTION
   7058    This routine is used to push the encoded video frames to
   7059    the video decoder.
   7060 
   7061    PARAMETERS
   7062    None.
   7063 
   7064    RETURN VALUE
   7065    OMX Error None if everything went successful.
   7066 
   7067    ========================================================================== */
   7068 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   7069         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7070 {
   7071     (void) hComp;
   7072     int push_cnt = 0,i=0;
   7073     unsigned nPortIndex = 0;
   7074     OMX_ERRORTYPE ret = OMX_ErrorNone;
   7075     struct vdec_input_frameinfo frameinfo;
   7076     struct vdec_bufferpayload *temp_buffer;
   7077     struct vdec_seqheader seq_header;
   7078     bool port_setting_changed = true;
   7079 
   7080     /*Should we generate a Aync error event*/
   7081     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   7082         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   7083         return OMX_ErrorBadParameter;
   7084     }
   7085 
   7086     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   7087 
   7088     if (nPortIndex >= drv_ctx.ip_buf.actualcount) {
   7089         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   7090                 nPortIndex);
   7091         return OMX_ErrorBadParameter;
   7092     }
   7093 
   7094     pending_input_buffers++;
   7095 
   7096     /* return zero length and not an EOS buffer */
   7097     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   7098             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   7099         DEBUG_PRINT_HIGH("return zero legth buffer");
   7100         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7101                 OMX_COMPONENT_GENERATE_EBD);
   7102         return OMX_ErrorNone;
   7103     }
   7104 
   7105     if (input_flush_progress == true) {
   7106         DEBUG_PRINT_LOW("Flush in progress return buffer ");
   7107         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   7108                 OMX_COMPONENT_GENERATE_EBD);
   7109         return OMX_ErrorNone;
   7110     }
   7111 
   7112     auto_lock l(buf_lock);
   7113     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   7114 
   7115     if (!temp_buffer || (temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
   7116         return OMX_ErrorBadParameter;
   7117     }
   7118     /* If its first frame, H264 codec and reject is true, then parse the nal
   7119        and get the profile. Based on this, reject the clip playback */
   7120     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   7121             m_reject_avc_1080p_mp) {
   7122         first_frame = 1;
   7123         DEBUG_PRINT_ERROR("Parse nal to get the profile");
   7124         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   7125                 NALU_TYPE_SPS);
   7126         m_profile = h264_parser->get_profile();
   7127         ret = is_video_session_supported();
   7128         if (ret) {
   7129             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   7130             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   7131             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   7132             m_state = OMX_StateInvalid;
   7133             return OMX_ErrorNone;
   7134         }
   7135     }
   7136 
   7137     DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7138     /*for use buffer we need to memcpy the data*/
   7139     temp_buffer->buffer_len = buffer->nFilledLen;
   7140 
   7141     if (input_use_buffer && temp_buffer->bufferaddr && !secure_mode) {
   7142         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   7143             if (arbitrary_bytes) {
   7144                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   7145             } else {
   7146                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   7147                         buffer->nFilledLen);
   7148             }
   7149         } else {
   7150             return OMX_ErrorBadParameter;
   7151         }
   7152 
   7153     }
   7154 
   7155     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   7156     frameinfo.client_data = (void *) buffer;
   7157     frameinfo.datalen = temp_buffer->buffer_len;
   7158     frameinfo.flags = 0;
   7159     frameinfo.offset = buffer->nOffset;
   7160     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   7161     frameinfo.pmem_offset = temp_buffer->offset;
   7162     frameinfo.timestamp = buffer->nTimeStamp;
   7163     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   7164         DEBUG_PRINT_LOW("ETB: dmx enabled");
   7165         if (m_demux_entries == 0) {
   7166             extract_demux_addr_offsets(buffer);
   7167         }
   7168 
   7169         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
   7170         handle_demux_data(buffer);
   7171         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   7172         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   7173     } else {
   7174         frameinfo.desc_addr = NULL;
   7175         frameinfo.desc_size = 0;
   7176     }
   7177     if (!arbitrary_bytes) {
   7178         frameinfo.flags |= buffer->nFlags;
   7179     }
   7180 
   7181 #ifdef _ANDROID_
   7182     if (m_debug_timestamp) {
   7183         if (arbitrary_bytes) {
   7184             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7185             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7186         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7187             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   7188             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   7189         }
   7190     }
   7191 #endif
   7192 
   7193     log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
   7194 
   7195 if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7196         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7197         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7198     }
   7199 
   7200     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7201         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
   7202         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   7203         h264_scratch.nFilledLen = 0;
   7204         nal_count = 0;
   7205         look_ahead_nal = false;
   7206         frame_count = 0;
   7207         if (m_frame_parser.mutils)
   7208             m_frame_parser.mutils->initialize_frame_checking_environment();
   7209         m_frame_parser.flush();
   7210         h264_last_au_ts = LLONG_MAX;
   7211         h264_last_au_flags = 0;
   7212         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   7213         m_demux_entries = 0;
   7214     }
   7215     struct v4l2_buffer buf;
   7216     struct v4l2_plane plane;
   7217     memset( (void *)&buf, 0, sizeof(buf));
   7218     memset( (void *)&plane, 0, sizeof(plane));
   7219     int rc;
   7220     unsigned long  print_count;
   7221     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7222         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   7223         DEBUG_PRINT_HIGH("INPUT EOS reached") ;
   7224     }
   7225     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7226     buf.index = nPortIndex;
   7227     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7228     buf.memory = V4L2_MEMORY_USERPTR;
   7229     plane.bytesused = temp_buffer->buffer_len;
   7230     plane.length = drv_ctx.ip_buf.buffer_size;
   7231     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   7232         (unsigned long)temp_buffer->offset;
   7233     plane.reserved[0] = temp_buffer->pmem_fd;
   7234     plane.reserved[1] = temp_buffer->offset;
   7235     plane.data_offset = 0;
   7236     buf.m.planes = &plane;
   7237     buf.length = 1;
   7238     if (frameinfo.timestamp >= LLONG_MAX) {
   7239         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   7240     }
   7241     //assumption is that timestamp is in milliseconds
   7242     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   7243     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   7244     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   7245     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   7246 
   7247     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7248         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
   7249         android_atomic_inc(&m_queued_codec_config_count);
   7250     }
   7251 
   7252     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7253     if (rc) {
   7254         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
   7255         return OMX_ErrorHardware;
   7256     }
   7257 
   7258     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7259         codec_config_flag = false;
   7260     }
   7261     if (!streaming[OUTPUT_PORT]) {
   7262         enum v4l2_buf_type buf_type;
   7263         int ret,r;
   7264 
   7265         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   7266         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   7267         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   7268         if (!ret) {
   7269             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
   7270             streaming[OUTPUT_PORT] = true;
   7271         } else if (errno == EBUSY) {
   7272             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
   7273             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7274                     OMX_COMPONENT_GENERATE_EBD);
   7275             return OMX_ErrorInsufficientResources;
   7276         } else {
   7277             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
   7278             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   7279             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   7280                     OMX_COMPONENT_GENERATE_EBD);
   7281             return OMX_ErrorBadParameter;
   7282         }
   7283     }
   7284     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
   7285             frameinfo.bufferaddr, (long long)frameinfo.timestamp,
   7286             (unsigned int)frameinfo.datalen);
   7287 
   7288     return ret;
   7289 }
   7290 
   7291 /* ======================================================================
   7292    FUNCTION
   7293    omx_vdec::FillThisBuffer
   7294 
   7295    DESCRIPTION
   7296    IL client uses this method to release the frame buffer
   7297    after displaying them.
   7298 
   7299    PARAMETERS
   7300    None.
   7301 
   7302    RETURN VALUE
   7303    true/false
   7304 
   7305    ========================================================================== */
   7306 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   7307         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   7308 {
   7309     if (m_state != OMX_StateExecuting &&
   7310             m_state != OMX_StatePause &&
   7311             m_state != OMX_StateIdle) {
   7312         DEBUG_PRINT_ERROR("FTB in Invalid State");
   7313         return OMX_ErrorInvalidState;
   7314     }
   7315 
   7316     if (!m_out_bEnabled) {
   7317         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   7318         return OMX_ErrorIncorrectStateOperation;
   7319     }
   7320 
   7321     unsigned nPortIndex = 0;
   7322     if (dynamic_buf_mode) {
   7323         private_handle_t *handle = NULL;
   7324         struct VideoDecoderOutputMetaData *meta;
   7325         unsigned int nPortIndex = 0;
   7326 
   7327         if (!buffer || !buffer->pBuffer) {
   7328             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
   7329             return OMX_ErrorBadParameter;
   7330         }
   7331 
   7332         //get the buffer type and fd info
   7333         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   7334         handle = (private_handle_t *)meta->pHandle;
   7335         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
   7336 
   7337         if (!handle) {
   7338             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
   7339             return OMX_ErrorBadParameter;
   7340         }
   7341         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   7342         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7343         if (nPortIndex < drv_ctx.op_buf.actualcount &&
   7344             nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   7345             drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   7346             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   7347 
   7348            //Store private handle from GraphicBuffer
   7349             native_buffer[nPortIndex].privatehandle = handle;
   7350             native_buffer[nPortIndex].nativehandle = handle;
   7351         } else {
   7352             DEBUG_PRINT_ERROR("[FTB]Invalid native_buffer index: %d", nPortIndex);
   7353             return OMX_ErrorBadParameter;
   7354         }
   7355 
   7356         //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
   7357         //this with a more sane size so that we don't compensate in rest of code
   7358         //We'll restore this size later on, so that it's transparent to client
   7359         buffer->nFilledLen = 0;
   7360         buffer->nAllocLen = handle->size;
   7361         drv_ctx.op_buf.buffer_size = handle->size;
   7362     }
   7363 
   7364     nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   7365     if (buffer == NULL ||
   7366             (nPortIndex >= drv_ctx.op_buf.actualcount)) {
   7367         DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7368             nPortIndex, drv_ctx.op_buf.actualcount);
   7369         return OMX_ErrorBadParameter;
   7370     }
   7371 
   7372     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   7373         DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
   7374         return OMX_ErrorBadPortIndex;
   7375     }
   7376 
   7377     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7378     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
   7379     return OMX_ErrorNone;
   7380 }
   7381 /* ======================================================================
   7382    FUNCTION
   7383    omx_vdec::fill_this_buffer_proxy
   7384 
   7385    DESCRIPTION
   7386    IL client uses this method to release the frame buffer
   7387    after displaying them.
   7388 
   7389    PARAMETERS
   7390    None.
   7391 
   7392    RETURN VALUE
   7393    true/false
   7394 
   7395    ========================================================================== */
   7396 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   7397         OMX_IN OMX_HANDLETYPE        hComp,
   7398         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   7399 {
   7400     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   7401     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   7402     unsigned nPortIndex = 0;
   7403     struct vdec_fillbuffer_cmd fillbuffer;
   7404     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   7405     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   7406 
   7407     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7408 
   7409     if (bufferAdd == NULL || nPortIndex >= drv_ctx.op_buf.actualcount) {
   7410         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   7411             nPortIndex, drv_ctx.op_buf.actualcount);
   7412         return OMX_ErrorBadParameter;
   7413     }
   7414 
   7415     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   7416             bufferAdd, bufferAdd->pBuffer);
   7417     /*Return back the output buffer to client*/
   7418     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
   7419         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
   7420         buffer->nFilledLen = 0;
   7421         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   7422         return OMX_ErrorNone;
   7423     }
   7424 
   7425     if (dynamic_buf_mode) {
   7426         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   7427         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = buffer->nAllocLen;
   7428         buf_ref_add(nPortIndex);
   7429         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = buffer->nAllocLen;
   7430     }
   7431 
   7432     pending_output_buffers++;
   7433     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   7434     if (!buffer) {
   7435        DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
   7436        return OMX_ErrorBadParameter;
   7437     }
   7438     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   7439     if (ptr_respbuffer) {
   7440         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   7441     }
   7442 
   7443     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   7444         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   7445         buffer->nFilledLen = 0;
   7446         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   7447         pending_output_buffers--;
   7448         return OMX_ErrorBadParameter;
   7449     }
   7450 
   7451     int rc = 0;
   7452     struct v4l2_buffer buf;
   7453     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   7454     memset( (void *)&buf, 0, sizeof(buf));
   7455     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   7456     unsigned int extra_idx = 0;
   7457 
   7458     buf.index = nPortIndex;
   7459     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   7460     buf.memory = V4L2_MEMORY_USERPTR;
   7461     plane[0].bytesused = buffer->nFilledLen;
   7462     plane[0].length = buffer->nAllocLen;
   7463     plane[0].m.userptr =
   7464         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   7465         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   7466     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   7467     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   7468     plane[0].data_offset = 0;
   7469     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   7470     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   7471         plane[extra_idx].bytesused = 0;
   7472         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   7473         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   7474 #ifdef USE_ION
   7475         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   7476 #endif
   7477         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   7478         plane[extra_idx].data_offset = 0;
   7479     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   7480         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   7481         return OMX_ErrorBadParameter;
   7482     }
   7483     buf.m.planes = plane;
   7484     buf.length = drv_ctx.num_planes;
   7485     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   7486              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], output_flush_progress);
   7487 
   7488     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   7489     if (rc) {
   7490         /*TODO: How to handle this case */
   7491         DEBUG_PRINT_ERROR("Failed to qbuf to driver");
   7492     }
   7493 return OMX_ErrorNone;
   7494 }
   7495 
   7496 /* ======================================================================
   7497    FUNCTION
   7498    omx_vdec::SetCallbacks
   7499 
   7500    DESCRIPTION
   7501    Set the callbacks.
   7502 
   7503    PARAMETERS
   7504    None.
   7505 
   7506    RETURN VALUE
   7507    OMX Error None if everything successful.
   7508 
   7509    ========================================================================== */
   7510 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   7511         OMX_IN OMX_CALLBACKTYPE* callbacks,
   7512         OMX_IN OMX_PTR             appData)
   7513 {
   7514     (void) hComp;
   7515     m_cb       = *callbacks;
   7516     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   7517             m_cb.EventHandler,m_cb.FillBufferDone);
   7518     m_app_data =    appData;
   7519     return OMX_ErrorNotImplemented;
   7520 }
   7521 
   7522 /* ======================================================================
   7523    FUNCTION
   7524    omx_vdec::ComponentDeInit
   7525 
   7526    DESCRIPTION
   7527    Destroys the component and release memory allocated to the heap.
   7528 
   7529    PARAMETERS
   7530    <TBD>.
   7531 
   7532    RETURN VALUE
   7533    OMX Error None if everything successful.
   7534 
   7535    ========================================================================== */
   7536 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   7537 {
   7538    (void) hComp;
   7539 
   7540     unsigned i = 0;
   7541     if (OMX_StateLoaded != m_state) {
   7542         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
   7543                 m_state);
   7544         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   7545     } else {
   7546         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
   7547     }
   7548 
   7549     /*Check if the output buffers have to be cleaned up*/
   7550     if (m_out_mem_ptr) {
   7551         DEBUG_PRINT_LOW("Freeing the Output Memory");
   7552         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   7553             if (BITMASK_PRESENT(&m_out_bm_count, i)) {
   7554                 BITMASK_CLEAR(&m_out_bm_count, i);
   7555                 client_buffers.free_output_buffer (&m_out_mem_ptr[i]);
   7556             }
   7557 
   7558             if (release_output_done()) {
   7559                 break;
   7560             }
   7561         }
   7562 #ifdef _ANDROID_ICS_
   7563         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   7564 #endif
   7565     }
   7566 
   7567     /*Check if the input buffers have to be cleaned up*/
   7568     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   7569         DEBUG_PRINT_LOW("Freeing the Input Memory");
   7570         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   7571 
   7572             if (BITMASK_PRESENT(&m_inp_bm_count, i)) {
   7573                 BITMASK_CLEAR(&m_inp_bm_count, i);
   7574                 if (m_inp_mem_ptr)
   7575                     free_input_buffer (i,&m_inp_mem_ptr[i]);
   7576                 else
   7577                     free_input_buffer (i,NULL);
   7578             }
   7579 
   7580             if (release_input_done()) {
   7581                 break;
   7582             }
   7583        }
   7584     }
   7585     free_input_buffer_header();
   7586     free_output_buffer_header();
   7587     if (h264_scratch.pBuffer) {
   7588         free(h264_scratch.pBuffer);
   7589         h264_scratch.pBuffer = NULL;
   7590     }
   7591 
   7592     if (h264_parser) {
   7593         delete h264_parser;
   7594         h264_parser = NULL;
   7595     }
   7596 
   7597     if (m_frame_parser.mutils) {
   7598         DEBUG_PRINT_LOW("Free utils parser");
   7599         delete (m_frame_parser.mutils);
   7600         m_frame_parser.mutils = NULL;
   7601     }
   7602 
   7603     if (m_platform_list) {
   7604         free(m_platform_list);
   7605         m_platform_list = NULL;
   7606     }
   7607     if (m_vendor_config.pData) {
   7608         free(m_vendor_config.pData);
   7609         m_vendor_config.pData = NULL;
   7610     }
   7611 
   7612     // Reset counters in mesg queues
   7613     m_ftb_q.m_size=0;
   7614     m_cmd_q.m_size=0;
   7615     m_etb_q.m_size=0;
   7616     m_ftb_q.m_read = m_ftb_q.m_write =0;
   7617     m_cmd_q.m_read = m_cmd_q.m_write =0;
   7618     m_etb_q.m_read = m_etb_q.m_write =0;
   7619 #ifdef _ANDROID_
   7620     if (m_debug_timestamp) {
   7621         m_timestamp_list.reset_ts_list();
   7622     }
   7623 #endif
   7624 
   7625     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
   7626     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   7627     // NULL);
   7628     DEBUG_PRINT_HIGH("Close the driver instance");
   7629 
   7630     if (m_debug.infile) {
   7631         fclose(m_debug.infile);
   7632         m_debug.infile = NULL;
   7633     }
   7634     if (m_debug.outfile) {
   7635         fclose(m_debug.outfile);
   7636         m_debug.outfile = NULL;
   7637     }
   7638     if (m_debug.out_ymeta_file) {
   7639         fclose(m_debug.out_ymeta_file);
   7640         m_debug.out_ymeta_file = NULL;
   7641     }
   7642     if (m_debug.out_uvmeta_file) {
   7643         fclose(m_debug.out_uvmeta_file);
   7644         m_debug.out_uvmeta_file = NULL;
   7645     }
   7646 #ifdef OUTPUT_EXTRADATA_LOG
   7647     if (outputExtradataFile)
   7648         fclose (outputExtradataFile);
   7649 #endif
   7650     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
   7651     return OMX_ErrorNone;
   7652 }
   7653 
   7654 /* ======================================================================
   7655    FUNCTION
   7656    omx_vdec::UseEGLImage
   7657 
   7658    DESCRIPTION
   7659    OMX Use EGL Image method implementation <TBD>.
   7660 
   7661    PARAMETERS
   7662    <TBD>.
   7663 
   7664    RETURN VALUE
   7665    Not Implemented error.
   7666 
   7667    ========================================================================== */
   7668 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
   7669         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   7670         OMX_IN OMX_U32                        port,
   7671         OMX_IN OMX_PTR                     appData,
   7672         OMX_IN void*                      eglImage)
   7673 {
   7674     (void) appData;
   7675     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   7676     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   7677     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   7678 
   7679 #ifdef USE_EGL_IMAGE_GPU
   7680     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   7681     EGLint fd = -1, offset = 0,pmemPtr = 0;
   7682 #else
   7683     int fd = -1, offset = 0;
   7684 #endif
   7685     DEBUG_PRINT_HIGH("use EGL image support for decoder");
   7686     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   7687         DEBUG_PRINT_ERROR("Invalid EGL image");
   7688     }
   7689 #ifdef USE_EGL_IMAGE_GPU
   7690     if (m_display_id == NULL) {
   7691         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
   7692         return OMX_ErrorInsufficientResources;
   7693     }
   7694     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   7695         eglGetProcAddress("eglQueryImageKHR");
   7696     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
   7697     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
   7698     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR, &pmemPtr);
   7699 #else //with OMX test app
   7700     struct temp_egl {
   7701         int pmem_fd;
   7702         int offset;
   7703     };
   7704     struct temp_egl *temp_egl_id = NULL;
   7705     void * pmemPtr = (void *) eglImage;
   7706     temp_egl_id = (struct temp_egl *)eglImage;
   7707     if (temp_egl_id != NULL) {
   7708         fd = temp_egl_id->pmem_fd;
   7709         offset = temp_egl_id->offset;
   7710     }
   7711 #endif
   7712     if (fd < 0) {
   7713         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
   7714         return OMX_ErrorInsufficientResources;
   7715     }
   7716     pmem_info.pmem_fd = (OMX_U32) fd;
   7717     pmem_info.offset = (OMX_U32) offset;
   7718     pmem_entry.entry = (void *) &pmem_info;
   7719     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   7720     pmem_list.entryList = &pmem_entry;
   7721     pmem_list.nEntries = 1;
   7722     ouput_egl_buffers = true;
   7723     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   7724                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   7725                 (OMX_U8 *)pmemPtr)) {
   7726         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
   7727         return OMX_ErrorInsufficientResources;
   7728     }
   7729     return OMX_ErrorNone;
   7730 }
   7731 
   7732 /* ======================================================================
   7733    FUNCTION
   7734    omx_vdec::ComponentRoleEnum
   7735 
   7736    DESCRIPTION
   7737    OMX Component Role Enum method implementation.
   7738 
   7739    PARAMETERS
   7740    <TBD>.
   7741 
   7742    RETURN VALUE
   7743    OMX Error None if everything is successful.
   7744    ========================================================================== */
   7745 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   7746         OMX_OUT OMX_U8*        role,
   7747         OMX_IN OMX_U32        index)
   7748 {
   7749     (void) hComp;
   7750     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   7751 
   7752     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   7753         if ((0 == index) && role) {
   7754             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   7755             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7756         } else {
   7757             eRet = OMX_ErrorNoMore;
   7758         }
   7759     }
   7760     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   7761         if ((0 == index) && role) {
   7762             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   7763             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7764         } else {
   7765             eRet = OMX_ErrorNoMore;
   7766         }
   7767     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   7768         if ((0 == index) && role) {
   7769             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   7770             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7771         } else {
   7772             DEBUG_PRINT_LOW("No more roles");
   7773             eRet = OMX_ErrorNoMore;
   7774         }
   7775     }
   7776 
   7777     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   7778             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) {
   7779         if ((0 == index) && role) {
   7780             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   7781             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7782         } else {
   7783             DEBUG_PRINT_LOW("No more roles");
   7784             eRet = OMX_ErrorNoMore;
   7785         }
   7786     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   7787         if ((0 == index) && role) {
   7788             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   7789             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7790         } else {
   7791             DEBUG_PRINT_LOW("No more roles");
   7792             eRet = OMX_ErrorNoMore;
   7793         }
   7794     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   7795         if ((0 == index) && role) {
   7796             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   7797             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7798         } else {
   7799             DEBUG_PRINT_LOW("No more roles");
   7800             eRet = OMX_ErrorNoMore;
   7801         }
   7802     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   7803         if ((0 == index) && role) {
   7804             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   7805             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   7806         } else {
   7807             DEBUG_PRINT_LOW("No more roles");
   7808             eRet = OMX_ErrorNoMore;
   7809         }
   7810     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   7811             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   7812           ) {
   7813         if ((0 == index) && role) {
   7814             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   7815             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7816         } else {
   7817             DEBUG_PRINT_LOW("No more roles");
   7818             eRet = OMX_ErrorNoMore;
   7819         }
   7820     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   7821         if ((0 == index) && role) {
   7822             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   7823             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7824         } else {
   7825             DEBUG_PRINT_LOW("No more roles");
   7826             eRet = OMX_ErrorNoMore;
   7827         }
   7828     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp9",OMX_MAX_STRINGNAME_SIZE)) {
   7829         if ((0 == index) && role) {
   7830             strlcpy((char *)role, "video_decoder.vp9",OMX_MAX_STRINGNAME_SIZE);
   7831             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   7832         } else {
   7833             DEBUG_PRINT_LOW("No more roles");
   7834             eRet = OMX_ErrorNoMore;
   7835         }
   7836     } else {
   7837         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
   7838         eRet = OMX_ErrorInvalidComponentName;
   7839     }
   7840     return eRet;
   7841 }
   7842 
   7843 
   7844 
   7845 
   7846 /* ======================================================================
   7847    FUNCTION
   7848    omx_vdec::AllocateDone
   7849 
   7850    DESCRIPTION
   7851    Checks if entire buffer pool is allocated by IL Client or not.
   7852    Need this to move to IDLE state.
   7853 
   7854    PARAMETERS
   7855    None.
   7856 
   7857    RETURN VALUE
   7858    true/false.
   7859 
   7860    ========================================================================== */
   7861 bool omx_vdec::allocate_done(void)
   7862 {
   7863     bool bRet = false;
   7864     bool bRet_In = false;
   7865     bool bRet_Out = false;
   7866 
   7867     bRet_In = allocate_input_done();
   7868     bRet_Out = allocate_output_done();
   7869 
   7870     if (bRet_In && bRet_Out) {
   7871         bRet = true;
   7872     }
   7873 
   7874     return bRet;
   7875 }
   7876 /* ======================================================================
   7877    FUNCTION
   7878    omx_vdec::AllocateInputDone
   7879 
   7880    DESCRIPTION
   7881    Checks if I/P buffer pool is allocated by IL Client or not.
   7882 
   7883    PARAMETERS
   7884    None.
   7885 
   7886    RETURN VALUE
   7887    true/false.
   7888 
   7889    ========================================================================== */
   7890 bool omx_vdec::allocate_input_done(void)
   7891 {
   7892     bool bRet = false;
   7893     unsigned i=0;
   7894 
   7895     if (m_inp_mem_ptr == NULL) {
   7896         return bRet;
   7897     }
   7898     if (m_inp_mem_ptr ) {
   7899         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   7900             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   7901                 break;
   7902             }
   7903         }
   7904     }
   7905     if (i == drv_ctx.ip_buf.actualcount) {
   7906         bRet = true;
   7907         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   7908     }
   7909     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   7910         m_inp_bPopulated = OMX_TRUE;
   7911     }
   7912     return bRet;
   7913 }
   7914 /* ======================================================================
   7915    FUNCTION
   7916    omx_vdec::AllocateOutputDone
   7917 
   7918    DESCRIPTION
   7919    Checks if entire O/P buffer pool is allocated by IL Client or not.
   7920 
   7921    PARAMETERS
   7922    None.
   7923 
   7924    RETURN VALUE
   7925    true/false.
   7926 
   7927    ========================================================================== */
   7928 bool omx_vdec::allocate_output_done(void)
   7929 {
   7930     bool bRet = false;
   7931     unsigned j=0;
   7932 
   7933     if (m_out_mem_ptr == NULL) {
   7934         return bRet;
   7935     }
   7936 
   7937     if (m_out_mem_ptr) {
   7938         for (; j < drv_ctx.op_buf.actualcount; j++) {
   7939             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   7940                 break;
   7941             }
   7942         }
   7943     }
   7944 
   7945     if (j == drv_ctx.op_buf.actualcount) {
   7946         bRet = true;
   7947         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   7948         if (m_out_bEnabled)
   7949             m_out_bPopulated = OMX_TRUE;
   7950     }
   7951 
   7952     return bRet;
   7953 }
   7954 
   7955 /* ======================================================================
   7956    FUNCTION
   7957    omx_vdec::ReleaseDone
   7958 
   7959    DESCRIPTION
   7960    Checks if IL client has released all the buffers.
   7961 
   7962    PARAMETERS
   7963    None.
   7964 
   7965    RETURN VALUE
   7966    true/false
   7967 
   7968    ========================================================================== */
   7969 bool omx_vdec::release_done(void)
   7970 {
   7971     bool bRet = false;
   7972 
   7973     if (release_input_done()) {
   7974         if (release_output_done()) {
   7975             bRet = true;
   7976         }
   7977     }
   7978     return bRet;
   7979 }
   7980 
   7981 
   7982 /* ======================================================================
   7983    FUNCTION
   7984    omx_vdec::ReleaseOutputDone
   7985 
   7986    DESCRIPTION
   7987    Checks if IL client has released all the buffers.
   7988 
   7989    PARAMETERS
   7990    None.
   7991 
   7992    RETURN VALUE
   7993    true/false
   7994 
   7995    ========================================================================== */
   7996 bool omx_vdec::release_output_done(void)
   7997 {
   7998     bool bRet = false;
   7999     unsigned i=0,j=0;
   8000 
   8001     DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p", m_out_mem_ptr);
   8002     if (m_out_mem_ptr) {
   8003         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   8004             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   8005                 break;
   8006             }
   8007         }
   8008         if (j == drv_ctx.op_buf.actualcount) {
   8009             m_out_bm_count = 0;
   8010             bRet = true;
   8011         }
   8012     } else {
   8013         m_out_bm_count = 0;
   8014         bRet = true;
   8015     }
   8016     return bRet;
   8017 }
   8018 /* ======================================================================
   8019    FUNCTION
   8020    omx_vdec::ReleaseInputDone
   8021 
   8022    DESCRIPTION
   8023    Checks if IL client has released all the buffers.
   8024 
   8025    PARAMETERS
   8026    None.
   8027 
   8028    RETURN VALUE
   8029    true/false
   8030 
   8031    ========================================================================== */
   8032 bool omx_vdec::release_input_done(void)
   8033 {
   8034     bool bRet = false;
   8035     unsigned i=0,j=0;
   8036 
   8037     DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   8038     if (m_inp_mem_ptr) {
   8039         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   8040             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   8041                 break;
   8042             }
   8043         }
   8044         if (j==drv_ctx.ip_buf.actualcount) {
   8045             bRet = true;
   8046         }
   8047     } else {
   8048         bRet = true;
   8049     }
   8050     return bRet;
   8051 }
   8052 
   8053 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   8054         OMX_BUFFERHEADERTYPE * buffer)
   8055 {
   8056     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   8057     if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
   8058         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
   8059         return OMX_ErrorBadParameter;
   8060     } else if (output_flush_progress) {
   8061         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   8062         buffer->nFilledLen = 0;
   8063         buffer->nTimeStamp = 0;
   8064         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   8065         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8066         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   8067     }
   8068 
   8069     if (m_debug_extradata) {
   8070         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   8071             DEBUG_PRINT_HIGH("***************************************************");
   8072             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   8073             DEBUG_PRINT_HIGH("***************************************************");
   8074         }
   8075 
   8076         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   8077             DEBUG_PRINT_HIGH("***************************************************");
   8078             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   8079             DEBUG_PRINT_HIGH("***************************************************");
   8080         }
   8081     }
   8082 
   8083 
   8084     DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, flags: 0x%x, timestamp: %lld",
   8085             buffer, buffer->pBuffer, buffer->nFlags, buffer->nTimeStamp);
   8086     pending_output_buffers --;
   8087 
   8088     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8089         DEBUG_PRINT_HIGH("Output EOS has been reached");
   8090         if (!output_flush_progress)
   8091             post_event((unsigned)NULL, (unsigned)NULL,
   8092                     OMX_COMPONENT_GENERATE_EOS_DONE);
   8093 
   8094         if (psource_frame) {
   8095             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   8096             psource_frame = NULL;
   8097         }
   8098         if (pdest_frame) {
   8099             pdest_frame->nFilledLen = 0;
   8100             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
   8101                     (unsigned)NULL);
   8102             pdest_frame = NULL;
   8103         }
   8104     }
   8105 
   8106     if (!output_flush_progress && (buffer->nFilledLen > 0)) {
   8107         // set the default colorspace advised by client, since the bitstream may be
   8108         // devoid of colorspace-info.
   8109         if (m_enable_android_native_buffers) {
   8110             ColorSpace_t color_space = ITU_R_601;
   8111 
   8112         // Disabled ?
   8113         // WA for VP8. Vp8 encoder does not embed color-info (yet!).
   8114         // Encoding RGBA results in 601-LR for all resolutions.
   8115         // This conflicts with the client't defaults which are based on resolution.
   8116         //   Eg: 720p will be encoded as 601-LR. Client will say 709.
   8117         // Re-enable this code once vp8 encoder generates color-info and hence the
   8118         // decoder will be able to override with the correct source color.
   8119 #if 0
   8120             switch (m_client_color_space.sAspects.mPrimaries) {
   8121                 case ColorAspects::PrimariesBT601_6_625:
   8122                 case ColorAspects::PrimariesBT601_6_525:
   8123                 {
   8124                     color_space = m_client_color_space.sAspects.mRange == ColorAspects::RangeFull ?
   8125                             ITU_R_601_FR : ITU_R_601;
   8126                     break;
   8127                 }
   8128                 case ColorAspects::PrimariesBT709_5:
   8129                 {
   8130                     color_space = ITU_R_709;
   8131                     break;
   8132                 }
   8133                 default:
   8134                 {
   8135                     break;
   8136                 }
   8137             }
   8138 #endif
   8139             DEBUG_PRINT_LOW("setMetaData for Color Space (client) = 0x%x (601=%u FR=%u 709=%u)",
   8140                     color_space, ITU_R_601, ITU_R_601_FR, ITU_R_709);
   8141             set_colorspace_in_handle(color_space, buffer - m_out_mem_ptr);
   8142         }
   8143         DEBUG_PRINT_LOW("Processing extradata");
   8144         handle_extradata(buffer);
   8145     }
   8146 
   8147 #ifdef OUTPUT_EXTRADATA_LOG
   8148     if (outputExtradataFile) {
   8149         int buf_index = buffer - m_out_mem_ptr;
   8150         OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
   8151 
   8152         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   8153         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   8154             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
   8155 
   8156         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
   8157             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
   8158                                     p_extra->nSize, p_extra->eType);
   8159             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   8160 
   8161             if (p_extra->eType == OMX_ExtraDataNone) {
   8162                 break;
   8163             }
   8164             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   8165         }
   8166     }
   8167 #endif
   8168 
   8169     /* For use buffer we need to copy the data */
   8170     if (!output_flush_progress) {
   8171         /* This is the error check for non-recoverable errros */
   8172         bool is_duplicate_ts_valid = true;
   8173         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   8174 
   8175         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   8176                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   8177                 output_capability == V4L2_PIX_FMT_DIVX ||
   8178                 output_capability == V4L2_PIX_FMT_DIVX_311)
   8179             is_duplicate_ts_valid = false;
   8180 
   8181         if ((output_capability == V4L2_PIX_FMT_H264 ||
   8182                 output_capability == V4L2_PIX_FMT_H264_MVC) &&
   8183                 is_interlaced) {
   8184             if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
   8185                 is_interlaced = false;
   8186             }
   8187         }
   8188 
   8189         if (buffer->nFilledLen > 0) {
   8190             time_stamp_dts.get_next_timestamp(buffer,
   8191                     is_interlaced && is_duplicate_ts_valid);
   8192             if (m_debug_timestamp) {
   8193                 {
   8194                     OMX_TICKS expected_ts = 0;
   8195                     m_timestamp_list.pop_min_ts(expected_ts);
   8196                     if (is_interlaced && is_duplicate_ts_valid) {
   8197                         m_timestamp_list.pop_min_ts(expected_ts);
   8198                     }
   8199                     DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   8200                             buffer->nTimeStamp, expected_ts);
   8201 
   8202                     if (buffer->nTimeStamp != expected_ts) {
   8203                         DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
   8204                     }
   8205                 }
   8206             }
   8207         }
   8208     }
   8209 
   8210     if (m_cb.FillBufferDone) {
   8211         if (buffer->nFilledLen > 0) {
   8212             if (arbitrary_bytes)
   8213                 adjust_timestamp(buffer->nTimeStamp);
   8214             else
   8215                 set_frame_rate(buffer->nTimeStamp);
   8216 
   8217             if (perf_flag) {
   8218                 if (!proc_frms) {
   8219                     dec_time.stop();
   8220                     latency = dec_time.processing_time_us() - latency;
   8221                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   8222                     dec_time.start();
   8223                     fps_metrics.start();
   8224                 }
   8225                 proc_frms++;
   8226                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8227                     OMX_U64 proc_time = 0;
   8228                     fps_metrics.stop();
   8229                     proc_time = fps_metrics.processing_time_us();
   8230                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
   8231                             (unsigned int)proc_frms, (float)proc_time / 1e6,
   8232                             (float)(1e6 * proc_frms) / proc_time);
   8233                     proc_frms = 0;
   8234                 }
   8235             }
   8236         }
   8237         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   8238             prev_ts = LLONG_MAX;
   8239             rst_prev_ts = true;
   8240         }
   8241 
   8242         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   8243             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   8244              buffer->pPlatformPrivate)->entryList->entry;
   8245         DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   8246         OMX_BUFFERHEADERTYPE *il_buffer;
   8247         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   8248         OMX_U32 current_framerate = (int)(drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator);
   8249 
   8250         if (il_buffer && m_last_rendered_TS >= 0) {
   8251             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
   8252 
   8253             // Current frame can be send for rendering if
   8254             // (a) current FPS is <=  60
   8255             // (b) is the next frame after the frame with TS 0
   8256             // (c) is the first frame after seek
   8257             // (d) the delta TS b\w two consecutive frames is > 16 ms
   8258             // (e) its TS is equal to previous frame TS
   8259             // (f) if marked EOS
   8260 
   8261             if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
   8262                il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
   8263                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   8264                m_last_rendered_TS = il_buffer->nTimeStamp;
   8265             } else {
   8266                //mark for droping
   8267                buffer->nFilledLen = 0;
   8268             }
   8269 
   8270             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
   8271                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
   8272                               il_buffer->nTimeStamp,ts_delta);
   8273 
   8274             //above code makes sure that delta b\w two consecutive frames is not
   8275             //greater than 16ms, slow-mo feature, so cap fps to max 60
   8276             if (current_framerate > 60 ) {
   8277                 current_framerate = 60;
   8278             }
   8279         }
   8280 
   8281         // add current framerate to gralloc meta data
   8282         if (m_enable_android_native_buffers && m_out_mem_ptr) {
   8283             OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8284             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   8285                          UPDATE_REFRESH_RATE, (void*)&current_framerate);
   8286         }
   8287 
   8288         if (il_buffer) {
   8289             log_output_buffers(il_buffer);
   8290             if (dynamic_buf_mode) {
   8291                 unsigned int nPortIndex = 0;
   8292                 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   8293 
   8294                 // Since we're passing around handles, adjust nFilledLen and nAllocLen
   8295                 // to size of the handle. Do it _after_ log_output_buffers which
   8296                 // requires the respective sizes to be accurate.
   8297 
   8298                 buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   8299                 buffer->nFilledLen = buffer->nFilledLen ?
   8300                         sizeof(struct VideoDecoderOutputMetaData) : 0;
   8301 
   8302                 //Clear graphic buffer handles in dynamic mode
   8303                 if (nPortIndex < drv_ctx.op_buf.actualcount &&
   8304                     nPortIndex < MAX_NUM_INPUT_OUTPUT_BUFFERS) {
   8305                     native_buffer[nPortIndex].privatehandle = NULL;
   8306                     native_buffer[nPortIndex].nativehandle = NULL;
   8307                 } else {
   8308                     DEBUG_PRINT_ERROR("[FBD]Invalid native_buffer index: %d", nPortIndex);
   8309                     return OMX_ErrorBadParameter;
   8310                 }
   8311             }
   8312             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   8313         } else {
   8314             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   8315             return OMX_ErrorBadParameter;
   8316         }
   8317         DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   8318     } else {
   8319         return OMX_ErrorBadParameter;
   8320     }
   8321 
   8322 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   8323     if (m_smoothstreaming_mode && m_out_mem_ptr) {
   8324         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   8325         BufferDim_t dim;
   8326         private_handle_t *private_handle = NULL;
   8327         dim.sliceWidth = framesize.nWidth;
   8328         dim.sliceHeight = framesize.nHeight;
   8329         if (buf_index < drv_ctx.op_buf.actualcount &&
   8330             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   8331             native_buffer[buf_index].privatehandle)
   8332             private_handle = native_buffer[buf_index].privatehandle;
   8333         if (private_handle) {
   8334             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   8335                 dim.sliceWidth, dim.sliceHeight);
   8336             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   8337         }
   8338     }
   8339 #endif
   8340 
   8341     return OMX_ErrorNone;
   8342 }
   8343 
   8344 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   8345         OMX_BUFFERHEADERTYPE* buffer)
   8346 {
   8347 
   8348     int nBufferIndex = buffer - m_inp_mem_ptr;
   8349 
   8350     if (buffer == NULL || (nBufferIndex >= (int)drv_ctx.ip_buf.actualcount)) {
   8351         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
   8352         return OMX_ErrorBadParameter;
   8353     }
   8354 
   8355     DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = 0x%x",
   8356             buffer, buffer->pBuffer, buffer->nFlags);
   8357     pending_input_buffers--;
   8358 
   8359     if (arbitrary_bytes) {
   8360         if (pdest_frame == NULL && input_flush_progress == false) {
   8361             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
   8362             pdest_frame = buffer;
   8363             buffer->nFilledLen = 0;
   8364             buffer->nTimeStamp = LLONG_MAX;
   8365             push_input_buffer (hComp);
   8366         } else {
   8367             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
   8368             buffer->nFilledLen = 0;
   8369             if (!m_input_free_q.insert_entry((unsigned long)buffer,
   8370                         (unsigned)NULL, (unsigned)NULL)) {
   8371                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
   8372             }
   8373         }
   8374     } else if (m_cb.EmptyBufferDone) {
   8375         buffer->nFilledLen = 0;
   8376         if (input_use_buffer == true) {
   8377             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   8378         }
   8379 
   8380         /* Restore the FD that we over-wrote in ETB */
   8381         if (m_input_pass_buffer_fd) {
   8382             buffer->pBuffer = (OMX_U8*)(uintptr_t)drv_ctx.ptr_inputbuffer[nBufferIndex].pmem_fd;
   8383         }
   8384 
   8385         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   8386     }
   8387     return OMX_ErrorNone;
   8388 }
   8389 
   8390 int omx_vdec::async_message_process (void *context, void* message)
   8391 {
   8392     omx_vdec* omx = NULL;
   8393     struct vdec_msginfo *vdec_msg = NULL;
   8394     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   8395     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   8396     struct vdec_output_frameinfo *output_respbuf = NULL;
   8397     int rc=1;
   8398     if (context == NULL || message == NULL) {
   8399         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
   8400         return -1;
   8401     }
   8402     vdec_msg = (struct vdec_msginfo *)message;
   8403 
   8404     omx = reinterpret_cast<omx_vdec*>(context);
   8405 
   8406     switch (vdec_msg->msgcode) {
   8407 
   8408         case VDEC_MSG_EVT_HW_ERROR:
   8409             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8410                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8411             break;
   8412 
   8413         case VDEC_MSG_EVT_HW_OVERLOAD:
   8414             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8415                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
   8416             break;
   8417 
   8418         case VDEC_MSG_EVT_HW_UNSUPPORTED:
   8419             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8420                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   8421             break;
   8422 
   8423         case VDEC_MSG_RESP_START_DONE:
   8424             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8425                     OMX_COMPONENT_GENERATE_START_DONE);
   8426             break;
   8427 
   8428         case VDEC_MSG_RESP_STOP_DONE:
   8429             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8430                     OMX_COMPONENT_GENERATE_STOP_DONE);
   8431             break;
   8432 
   8433         case VDEC_MSG_RESP_RESUME_DONE:
   8434             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8435                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   8436             break;
   8437 
   8438         case VDEC_MSG_RESP_PAUSE_DONE:
   8439             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8440                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   8441             break;
   8442 
   8443         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   8444             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8445                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   8446             break;
   8447         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   8448             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8449                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   8450             break;
   8451         case VDEC_MSG_RESP_INPUT_FLUSHED:
   8452         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   8453 
   8454             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   8455                vdec_msg->msgdata.input_frame_clientdata; */
   8456 
   8457             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   8458             if (omx->m_inp_mem_ptr == NULL || v4l2_buf_ptr == NULL ||
   8459                 v4l2_buf_ptr->index >= omx->drv_ctx.ip_buf.actualcount) {
   8460                 omxhdr = NULL;
   8461                 vdec_msg->status_code = VDEC_S_EFATAL;
   8462                 break;
   8463 
   8464             }
   8465             omxhdr = omx->m_inp_mem_ptr + v4l2_buf_ptr->index;
   8466 
   8467             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   8468                 DEBUG_PRINT_HIGH("Unsupported input");
   8469                 omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   8470                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8471             }
   8472             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   8473                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   8474                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   8475             }
   8476             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   8477 
   8478                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
   8479                 android_atomic_dec(&omx->m_queued_codec_config_count);
   8480                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
   8481                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
   8482                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
   8483                     sem_post(&omx->m_safe_flush);
   8484                 }
   8485             }
   8486             if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME ||
   8487                 v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   8488                 omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   8489             }
   8490             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
   8491                     OMX_COMPONENT_GENERATE_EBD);
   8492             break;
   8493         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   8494             int64_t *timestamp;
   8495             timestamp = (int64_t *) malloc(sizeof(int64_t));
   8496             if (timestamp) {
   8497                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   8498                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
   8499                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   8500                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
   8501                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
   8502             }
   8503             break;
   8504         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   8505         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   8506 
   8507            v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   8508 
   8509            if (v4l2_buf_ptr == NULL || omx->m_out_mem_ptr == NULL ||
   8510                v4l2_buf_ptr->index >= omx->drv_ctx.op_buf.actualcount) {
   8511                omxhdr = NULL;
   8512                vdec_msg->status_code = VDEC_S_EFATAL;
   8513                break;
   8514            }
   8515 
   8516            omxhdr = omx->m_out_mem_ptr + v4l2_buf_ptr->index;
   8517 
   8518             DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
   8519                     omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
   8520                     vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
   8521                     (unsigned int)vdec_msg->msgdata.output_frame.len,
   8522                     vdec_msg->msgdata.output_frame.framesize.left,
   8523                     vdec_msg->msgdata.output_frame.framesize.top,
   8524                     vdec_msg->msgdata.output_frame.framesize.right,
   8525                     vdec_msg->msgdata.output_frame.framesize.bottom);
   8526 
   8527             if (omxhdr && omxhdr->pOutputPortPrivate &&
   8528                     ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
   8529                     (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   8530                       - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
   8531 
   8532                 if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   8533                     omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   8534                     omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   8535                     omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   8536                     omxhdr->nFlags = 0;
   8537 
   8538                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
   8539                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   8540                         //rc = -1;
   8541                     }
   8542                     if (omxhdr->nFilledLen) {
   8543                         omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   8544                     }
   8545                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   8546                         omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   8547                     } else {
   8548                         omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   8549                     }
   8550                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   8551                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   8552                     }
   8553                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   8554                         omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   8555                     }
   8556 
   8557                     if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
   8558                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
   8559                     }
   8560 
   8561                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   8562                          omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
   8563                          DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   8564                                     omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   8565                     }
   8566 
   8567                     if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   8568                             !omx->output_flush_progress &&
   8569                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   8570                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
   8571                         unsigned int index = v4l2_buf_ptr->index;
   8572                         unsigned int extra_idx = EXTRADATA_IDX(omx->drv_ctx.num_planes);
   8573                         struct v4l2_plane *plane = v4l2_buf_ptr->m.planes;
   8574                         omx->time_stamp_dts.remove_time_stamp(
   8575                                 omxhdr->nTimeStamp,
   8576                                 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   8577                                 ?true:false);
   8578                         plane[0].bytesused = 0;
   8579                         plane[0].m.userptr =
   8580                             (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].bufferaddr -
   8581                             (unsigned long)omx->drv_ctx.ptr_outputbuffer[index].offset;
   8582                         plane[0].reserved[0] = omx->drv_ctx.ptr_outputbuffer[index].pmem_fd;
   8583                         plane[0].reserved[1] = omx->drv_ctx.ptr_outputbuffer[index].offset;
   8584                         plane[0].data_offset = 0;
   8585                         v4l2_buf_ptr->flags = 0x0;
   8586                         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   8587                             plane[extra_idx].bytesused = 0;
   8588                             plane[extra_idx].length = omx->drv_ctx.extradata_info.buffer_size;
   8589                             plane[extra_idx].m.userptr = (long unsigned int) (omx->drv_ctx.extradata_info.uaddr + index * omx->drv_ctx.extradata_info.buffer_size);
   8590 #ifdef USE_ION
   8591                             plane[extra_idx].reserved[0] = omx->drv_ctx.extradata_info.ion.fd_ion_data.fd;
   8592 #endif
   8593                             plane[extra_idx].reserved[1] = v4l2_buf_ptr->index * omx->drv_ctx.extradata_info.buffer_size;
   8594                             plane[extra_idx].data_offset = 0;
   8595                         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   8596                             DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   8597                             return -1;
   8598                         }
   8599 
   8600                          DEBUG_PRINT_LOW("SENDING FTB TO F/W from async_message_process - fd[0] = %d fd[1] = %d offset[1] = %d in_flush = %d",
   8601                                plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1], omx->output_flush_progress);
   8602                         if(ioctl(omx->drv_ctx.video_driver_fd, VIDIOC_QBUF, v4l2_buf_ptr)) {
   8603                             DEBUG_PRINT_ERROR("Failed to queue buffer back to driver: %d, %d, %d", v4l2_buf_ptr->length, v4l2_buf_ptr->m.planes[0].reserved[0], v4l2_buf_ptr->m.planes[1].reserved[0]);
   8604                             return -1;
   8605                         }
   8606                         break;
   8607                     }
   8608                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   8609                         omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   8610                     }
   8611                     vdec_msg->msgdata.output_frame.bufferaddr =
   8612                         omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   8613 
   8614                     /* Post event if resolution OR crop changed */
   8615                     /* filled length will be changed if resolution changed */
   8616                     /* Crop parameters can be changed even without resolution change */
   8617                     if (omxhdr->nFilledLen
   8618                         && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
   8619                         || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
   8620                         || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
   8621                         || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
   8622                         || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
   8623                         || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
   8624                         || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
   8625 
   8626                         DEBUG_PRINT_HIGH("Paramters Changed From: Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u --> Len: %u, WxH: %dx%d, L: %u, T: %u, R: %u, B: %u",
   8627                                 omx->prev_n_filled_len,
   8628                                 omx->drv_ctx.video_resolution.frame_width,
   8629                                 omx->drv_ctx.video_resolution.frame_height,
   8630                                 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
   8631                                 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
   8632                                 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
   8633                                 vdec_msg->msgdata.output_frame.picsize.frame_height,
   8634                                 vdec_msg->msgdata.output_frame.framesize.left,
   8635                                 vdec_msg->msgdata.output_frame.framesize.top,
   8636                                 vdec_msg->msgdata.output_frame.framesize.right,
   8637                                 vdec_msg->msgdata.output_frame.framesize.bottom);
   8638 
   8639                         omx->drv_ctx.video_resolution.frame_width =
   8640                                 vdec_msg->msgdata.output_frame.picsize.frame_width;
   8641                         omx->drv_ctx.video_resolution.frame_height =
   8642                                 vdec_msg->msgdata.output_frame.picsize.frame_height;
   8643                         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   8644                             omx->drv_ctx.video_resolution.stride =
   8645                                 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
   8646                             omx->drv_ctx.video_resolution.scan_lines =
   8647                                 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
   8648                         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   8649                             omx->drv_ctx.video_resolution.stride =
   8650                                 VENUS_Y_STRIDE(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_width);
   8651                             omx->drv_ctx.video_resolution.scan_lines =
   8652                                 VENUS_Y_SCANLINES(COLOR_FMT_NV12_UBWC, omx->drv_ctx.video_resolution.frame_height);
   8653                         }
   8654 
   8655                         memcpy(&omx->drv_ctx.frame_size,
   8656                                 &vdec_msg->msgdata.output_frame.framesize,
   8657                                 sizeof(struct vdec_framesize));
   8658 
   8659                         omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   8660                                 OMX_IndexConfigCommonOutputCrop,
   8661                                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   8662                     }
   8663 
   8664                     if (omxhdr->nFilledLen)
   8665                         omx->prev_n_filled_len = omxhdr->nFilledLen;
   8666 
   8667                     output_respbuf = (struct vdec_output_frameinfo *)\
   8668                              omxhdr->pOutputPortPrivate;
   8669                     if (!output_respbuf) {
   8670                       DEBUG_PRINT_ERROR("async_message_process: invalid output buf received");
   8671                       return -1;
   8672                     }
   8673                     output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   8674                     output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   8675 
   8676                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   8677                         output_respbuf->pic_type = PICTURE_TYPE_I;
   8678                     }
   8679                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   8680                         output_respbuf->pic_type = PICTURE_TYPE_P;
   8681                     }
   8682                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   8683                         output_respbuf->pic_type = PICTURE_TYPE_B;
   8684                     }
   8685                     if (omxhdr && omxhdr->nFilledLen) {
   8686                         omx->request_perf_level(VIDC_NOMINAL);
   8687                     }
   8688                     if (omx->output_use_buffer && omxhdr->pBuffer &&
   8689                         vdec_msg->msgdata.output_frame.bufferaddr)
   8690                         memcpy ( omxhdr->pBuffer, (void *)
   8691                                 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   8692                                  (unsigned long)vdec_msg->msgdata.output_frame.offset),
   8693                                 vdec_msg->msgdata.output_frame.len);
   8694                 } else {
   8695                     DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
   8696                             (unsigned int)vdec_msg->msgdata.output_frame.len,
   8697                             omxhdr->nAllocLen, omx->prev_n_filled_len);
   8698                     omxhdr->nFilledLen = 0;
   8699                 }
   8700 
   8701                 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
   8702                         OMX_COMPONENT_GENERATE_FBD);
   8703 
   8704             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
   8705                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
   8706                         OMX_COMPONENT_GENERATE_EOS_DONE);
   8707             } else {
   8708                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   8709                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   8710             }
   8711             break;
   8712         case VDEC_MSG_EVT_CONFIG_CHANGED:
   8713             DEBUG_PRINT_HIGH("Port settings changed");
   8714             omx->m_reconfig_width = vdec_msg->msgdata.output_frame.picsize.frame_width;
   8715             omx->m_reconfig_height = vdec_msg->msgdata.output_frame.picsize.frame_height;
   8716             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   8717                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   8718             omx->request_perf_level(VIDC_NOMINAL);
   8719             break;
   8720         default:
   8721             break;
   8722     }
   8723     return rc;
   8724 }
   8725 
   8726 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   8727         OMX_HANDLETYPE hComp,
   8728         OMX_BUFFERHEADERTYPE *buffer
   8729         )
   8730 {
   8731     unsigned address,p2,id;
   8732     DEBUG_PRINT_LOW("Empty this arbitrary");
   8733 
   8734     if (buffer == NULL) {
   8735         return OMX_ErrorBadParameter;
   8736     }
   8737     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   8738     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
   8739             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
   8740 
   8741     /* return zero length and not an EOS buffer */
   8742     /* return buffer if input flush in progress */
   8743     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   8744                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   8745         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
   8746         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   8747         return OMX_ErrorNone;
   8748     }
   8749 
   8750     if (psource_frame == NULL) {
   8751         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   8752         psource_frame = buffer;
   8753         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
   8754         push_input_buffer (hComp);
   8755     } else {
   8756         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
   8757         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
   8758                     (unsigned)NULL)) {
   8759             return OMX_ErrorBadParameter;
   8760         }
   8761     }
   8762 
   8763     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   8764         codec_config_flag = false;
   8765     }
   8766     return OMX_ErrorNone;
   8767 }
   8768 
   8769 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   8770 {
   8771     unsigned long address,p2,id;
   8772     OMX_ERRORTYPE ret = OMX_ErrorNone;
   8773 
   8774     if (pdest_frame == NULL || psource_frame == NULL) {
   8775         /*Check if we have a destination buffer*/
   8776         if (pdest_frame == NULL) {
   8777             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
   8778             if (m_input_free_q.m_size) {
   8779                 m_input_free_q.pop_entry(&address,&p2,&id);
   8780                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   8781                 pdest_frame->nFilledLen = 0;
   8782                 pdest_frame->nTimeStamp = LLONG_MAX;
   8783                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
   8784             }
   8785         }
   8786 
   8787         /*Check if we have a destination buffer*/
   8788         if (psource_frame == NULL) {
   8789             DEBUG_PRINT_LOW("Get a source buffer from the queue");
   8790             if (m_input_pending_q.m_size) {
   8791                 m_input_pending_q.pop_entry(&address,&p2,&id);
   8792                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   8793                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   8794                         psource_frame->nTimeStamp);
   8795                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   8796                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   8797 
   8798             }
   8799         }
   8800 
   8801     }
   8802 
   8803     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   8804         switch (codec_type_parse) {
   8805             case CODEC_TYPE_MPEG4:
   8806             case CODEC_TYPE_H263:
   8807             case CODEC_TYPE_MPEG2:
   8808                 ret =  push_input_sc_codec(hComp);
   8809                 break;
   8810             case CODEC_TYPE_H264:
   8811                 ret = push_input_h264(hComp);
   8812                 break;
   8813             case CODEC_TYPE_HEVC:
   8814                 ret = push_input_hevc(hComp);
   8815                 break;
   8816             case CODEC_TYPE_VC1:
   8817                 ret = push_input_vc1(hComp);
   8818                 break;
   8819             default:
   8820                 break;
   8821         }
   8822         if (ret != OMX_ErrorNone) {
   8823             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
   8824             omx_report_error ();
   8825             break;
   8826         }
   8827     }
   8828 
   8829     return ret;
   8830 }
   8831 
   8832 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   8833 {
   8834     OMX_U32 partial_frame = 1;
   8835     OMX_BOOL generate_ebd = OMX_TRUE;
   8836     unsigned long address = 0, p2 = 0, id = 0;
   8837 
   8838     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
   8839             psource_frame,psource_frame->nTimeStamp);
   8840     if (m_frame_parser.parse_sc_frame(psource_frame,
   8841                 pdest_frame,&partial_frame) == -1) {
   8842         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   8843         return OMX_ErrorBadParameter;
   8844     }
   8845 
   8846     if (partial_frame == 0) {
   8847         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
   8848                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
   8849 
   8850 
   8851         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
   8852         /*First Parsed buffer will have only header Hence skip*/
   8853         if (frame_count == 0) {
   8854             DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
   8855 
   8856             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   8857                     codec_type_parse == CODEC_TYPE_DIVX) {
   8858                 mp4StreamType psBits;
   8859                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   8860                 psBits.numBytes = pdest_frame->nFilledLen;
   8861                 mp4_headerparser.parseHeader(&psBits);
   8862             }
   8863 
   8864             frame_count++;
   8865         } else {
   8866             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   8867             if (pdest_frame->nFilledLen) {
   8868                 /*Push the frame to the Decoder*/
   8869                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8870                     return OMX_ErrorBadParameter;
   8871                 }
   8872                 frame_count++;
   8873                 pdest_frame = NULL;
   8874 
   8875                 if (m_input_free_q.m_size) {
   8876                     m_input_free_q.pop_entry(&address,&p2,&id);
   8877                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   8878                     pdest_frame->nFilledLen = 0;
   8879                 }
   8880             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   8881                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
   8882                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
   8883                         (unsigned)NULL);
   8884                 pdest_frame = NULL;
   8885             }
   8886         }
   8887     } else {
   8888         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
   8889         /*Check if Destination Buffer is full*/
   8890         if (pdest_frame->nAllocLen ==
   8891                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   8892             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
   8893             return OMX_ErrorStreamCorrupt;
   8894         }
   8895     }
   8896 
   8897     if (psource_frame->nFilledLen == 0) {
   8898         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   8899             if (pdest_frame) {
   8900                 pdest_frame->nFlags |= psource_frame->nFlags;
   8901                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
   8902                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   8903                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   8904                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   8905                 /*Push the frame to the Decoder*/
   8906                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8907                     return OMX_ErrorBadParameter;
   8908                 }
   8909                 frame_count++;
   8910                 pdest_frame = NULL;
   8911             } else {
   8912                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
   8913                 generate_ebd = OMX_FALSE;
   8914             }
   8915         }
   8916         if (generate_ebd) {
   8917             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
   8918             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   8919             psource_frame = NULL;
   8920 
   8921             if (m_input_pending_q.m_size) {
   8922                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   8923                 m_input_pending_q.pop_entry(&address,&p2,&id);
   8924                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   8925                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   8926                         psource_frame->nTimeStamp);
   8927                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   8928                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   8929             }
   8930         }
   8931     }
   8932     return OMX_ErrorNone;
   8933 }
   8934 
   8935 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   8936 {
   8937     OMX_U32 partial_frame = 1;
   8938     unsigned long address = 0, p2 = 0, id = 0;
   8939     OMX_BOOL isNewFrame = OMX_FALSE;
   8940     OMX_BOOL generate_ebd = OMX_TRUE;
   8941 
   8942     if (h264_scratch.pBuffer == NULL) {
   8943         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
   8944         return OMX_ErrorBadParameter;
   8945     }
   8946     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
   8947             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
   8948     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
   8949     if (h264_scratch.nFilledLen && look_ahead_nal) {
   8950         look_ahead_nal = false;
   8951         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8952                 h264_scratch.nFilledLen) {
   8953             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8954                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8955             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8956             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
   8957             h264_scratch.nFilledLen = 0;
   8958         } else {
   8959             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
   8960             return OMX_ErrorBadParameter;
   8961         }
   8962     }
   8963 
   8964     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   8965        in EOS flag getting associated with the destination
   8966     */
   8967     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   8968             pdest_frame->nFilledLen) {
   8969         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   8970         generate_ebd = OMX_FALSE;
   8971     }
   8972 
   8973     if (nal_length == 0) {
   8974         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
   8975         if (m_frame_parser.parse_sc_frame(psource_frame,
   8976                     &h264_scratch,&partial_frame) == -1) {
   8977             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   8978             return OMX_ErrorBadParameter;
   8979         }
   8980     } else {
   8981         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   8982         if (m_frame_parser.parse_h264_nallength(psource_frame,
   8983                     &h264_scratch,&partial_frame) == -1) {
   8984             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   8985             return OMX_ErrorBadParameter;
   8986         }
   8987     }
   8988 
   8989     if (partial_frame == 0) {
   8990         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   8991             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   8992             nal_count++;
   8993             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   8994             h264_scratch.nFlags = psource_frame->nFlags;
   8995         } else {
   8996             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
   8997             if (h264_scratch.nFilledLen) {
   8998                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   8999                         NALU_TYPE_SPS);
   9000 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9001                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   9002                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9003                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9004                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9005                     // If timeinfo is present frame info from SEI is already processed
   9006                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   9007                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   9008 #endif
   9009                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9010                 nal_count++;
   9011                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   9012                     pdest_frame->nTimeStamp = h264_last_au_ts;
   9013                     pdest_frame->nFlags = h264_last_au_flags;
   9014 #ifdef PANSCAN_HDLR
   9015                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   9016                         h264_parser->update_panscan_data(h264_last_au_ts);
   9017 #endif
   9018                 }
   9019                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   9020                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   9021                     h264_last_au_ts = h264_scratch.nTimeStamp;
   9022                     h264_last_au_flags = h264_scratch.nFlags;
   9023 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9024                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9025                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   9026                         if (!VALID_TS(h264_last_au_ts))
   9027                             h264_last_au_ts = ts_in_sei;
   9028                     }
   9029 #endif
   9030                 } else
   9031                     h264_last_au_ts = LLONG_MAX;
   9032             }
   9033 
   9034             if (!isNewFrame) {
   9035                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9036                         h264_scratch.nFilledLen) {
   9037                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
   9038                             (unsigned int)h264_scratch.nFilledLen);
   9039                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9040                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9041                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9042                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   9043                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   9044                     h264_scratch.nFilledLen = 0;
   9045                 } else {
   9046                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
   9047                     return OMX_ErrorBadParameter;
   9048                 }
   9049             } else if(h264_scratch.nFilledLen) {
   9050                 look_ahead_nal = true;
   9051                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
   9052                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9053                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   9054                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   9055 
   9056                 if (pdest_frame->nFilledLen == 0) {
   9057                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
   9058                     look_ahead_nal = false;
   9059                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9060                             h264_scratch.nFilledLen) {
   9061                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9062                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9063                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9064                         h264_scratch.nFilledLen = 0;
   9065                     } else {
   9066                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
   9067                         return OMX_ErrorBadParameter;
   9068                     }
   9069                 } else {
   9070                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   9071                         DEBUG_PRINT_LOW("Reset the EOS Flag");
   9072                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9073                     }
   9074                     /*Push the frame to the Decoder*/
   9075                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9076                         return OMX_ErrorBadParameter;
   9077                     }
   9078                     //frame_count++;
   9079                     pdest_frame = NULL;
   9080                     if (m_input_free_q.m_size) {
   9081                         m_input_free_q.pop_entry(&address,&p2,&id);
   9082                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9083                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
   9084                         pdest_frame->nFilledLen = 0;
   9085                         pdest_frame->nFlags = 0;
   9086                         pdest_frame->nTimeStamp = LLONG_MAX;
   9087                     }
   9088                 }
   9089             }
   9090         }
   9091     } else {
   9092         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
   9093         /*Check if Destination Buffer is full*/
   9094         if (h264_scratch.nAllocLen ==
   9095                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   9096             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   9097             return OMX_ErrorStreamCorrupt;
   9098         }
   9099     }
   9100 
   9101     if (!psource_frame->nFilledLen) {
   9102         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
   9103 
   9104         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9105             if (pdest_frame) {
   9106                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   9107                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   9108                         h264_scratch.nFilledLen) {
   9109                     if(pdest_frame->nFilledLen == 0) {
   9110                         /* No residual frame from before, send whatever
   9111                          * we have left */
   9112                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9113                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   9114                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9115                         h264_scratch.nFilledLen = 0;
   9116                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   9117                     } else {
   9118                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   9119                         if(!isNewFrame) {
   9120                             /* Have a residual frame, but we know that the
   9121                              * AU in this frame is belonging to whatever
   9122                              * frame we had left over.  So append it */
   9123                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   9124                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   9125                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   9126                              h264_scratch.nFilledLen = 0;
   9127                              if (h264_last_au_ts != LLONG_MAX)
   9128                                  pdest_frame->nTimeStamp = h264_last_au_ts;
   9129                         } else {
   9130                             /* Completely new frame, let's just push what
   9131                              * we have now.  The resulting EBD would trigger
   9132                              * another push */
   9133                             generate_ebd = OMX_FALSE;
   9134                             pdest_frame->nTimeStamp = h264_last_au_ts;
   9135                             h264_last_au_ts = h264_scratch.nTimeStamp;
   9136                         }
   9137                     }
   9138                 } else {
   9139                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
   9140                     return OMX_ErrorBadParameter;
   9141                 }
   9142 
   9143                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   9144                 if(generate_ebd == OMX_TRUE) {
   9145                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9146                 }
   9147 
   9148                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
   9149                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   9150                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
   9151 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   9152                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   9153                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   9154                     if (!VALID_TS(pdest_frame->nTimeStamp))
   9155                         pdest_frame->nTimeStamp = ts_in_sei;
   9156                 }
   9157 #endif
   9158                 /*Push the frame to the Decoder*/
   9159                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   9160                     return OMX_ErrorBadParameter;
   9161                 }
   9162                 frame_count++;
   9163                 pdest_frame = NULL;
   9164             } else {
   9165                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9166                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9167                 generate_ebd = OMX_FALSE;
   9168             }
   9169         }
   9170     }
   9171     if (generate_ebd && !psource_frame->nFilledLen) {
   9172         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   9173         psource_frame = NULL;
   9174         if (m_input_pending_q.m_size) {
   9175             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   9176             m_input_pending_q.pop_entry(&address,&p2,&id);
   9177             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   9178             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
   9179                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   9180         }
   9181     }
   9182     return OMX_ErrorNone;
   9183 }
   9184 
   9185 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
   9186 {
   9187     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9188     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
   9189         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
   9190         if (pDst->nTimeStamp == LLONG_MAX) {
   9191             pDst->nTimeStamp = pSrc->nTimeStamp;
   9192             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
   9193         }
   9194         pDst->nFilledLen += pSrc->nFilledLen;
   9195         pSrc->nFilledLen = 0;
   9196     } else {
   9197         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
   9198         rc = OMX_ErrorBadParameter;
   9199     }
   9200     return rc;
   9201 }
   9202 
   9203 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
   9204 {
   9205     OMX_U32 partial_frame = 1;
   9206     unsigned long address,p2,id;
   9207     OMX_BOOL isNewFrame = OMX_FALSE;
   9208     OMX_BOOL generate_ebd = OMX_TRUE;
   9209     OMX_ERRORTYPE rc = OMX_ErrorNone;
   9210     if (h264_scratch.pBuffer == NULL) {
   9211         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
   9212         return OMX_ErrorBadParameter;
   9213     }
   9214 
   9215     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
   9216             pdest_frame nFilledLen %u nTimeStamp %lld",
   9217             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9218 
   9219     if (h264_scratch.nFilledLen && look_ahead_nal) {
   9220         look_ahead_nal = false;
   9221         rc = copy_buffer(pdest_frame, &h264_scratch);
   9222         if (rc != OMX_ErrorNone) {
   9223             return rc;
   9224         }
   9225     }
   9226 
   9227     if (nal_length == 0) {
   9228         if (m_frame_parser.parse_sc_frame(psource_frame,
   9229                     &h264_scratch,&partial_frame) == -1) {
   9230             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   9231             return OMX_ErrorBadParameter;
   9232         }
   9233     } else {
   9234         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
   9235         if (m_frame_parser.parse_h264_nallength(psource_frame,
   9236                     &h264_scratch,&partial_frame) == -1) {
   9237             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   9238             return OMX_ErrorBadParameter;
   9239         }
   9240     }
   9241 
   9242     if (partial_frame == 0) {
   9243         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   9244             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   9245             nal_count++;
   9246             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   9247             h264_scratch.nFlags = psource_frame->nFlags;
   9248         } else {
   9249             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
   9250             if (h264_scratch.nFilledLen) {
   9251                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
   9252                 nal_count++;
   9253             }
   9254 
   9255             if (!isNewFrame) {
   9256                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
   9257                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
   9258                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
   9259                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9260                 rc = copy_buffer(pdest_frame, &h264_scratch);
   9261                 if (rc != OMX_ErrorNone) {
   9262                     return rc;
   9263                 }
   9264             } else {
   9265                 look_ahead_nal = true;
   9266                 if (pdest_frame->nFilledLen == 0) {
   9267                     look_ahead_nal = false;
   9268                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
   9269                     rc = copy_buffer(pdest_frame, &h264_scratch);
   9270                     if (rc != OMX_ErrorNone) {
   9271                         return OMX_ErrorBadParameter;
   9272                     }
   9273                 } else {
   9274                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   9275                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   9276                     }
   9277                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
   9278                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
   9279                             nFilledLen %u nTimeStamp %lld",
   9280                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
   9281                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
   9282                             h264_scratch.nTimeStamp);
   9283                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   9284                         return OMX_ErrorBadParameter;
   9285                     }
   9286                     pdest_frame = NULL;
   9287                     if (m_input_free_q.m_size) {
   9288                         m_input_free_q.pop_entry(&address, &p2, &id);
   9289                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   9290                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
   9291                         pdest_frame->nFilledLen = 0;
   9292                         pdest_frame->nFlags = 0;
   9293                         pdest_frame->nTimeStamp = LLONG_MAX;
   9294                     }
   9295                 }
   9296             }
   9297         }
   9298     } else {
   9299         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
   9300                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
   9301                 nFilledLen %u nTimeStamp %lld",
   9302                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
   9303                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
   9304                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
   9305 
   9306         if (h264_scratch.nAllocLen ==
   9307                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   9308             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   9309             return OMX_ErrorStreamCorrupt;
   9310         }
   9311     }
   9312 
   9313     if (!psource_frame->nFilledLen) {
   9314         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
   9315         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   9316             if (pdest_frame) {
   9317                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   9318                 rc = copy_buffer(pdest_frame, &h264_scratch);
   9319                 if ( rc != OMX_ErrorNone ) {
   9320                     return rc;
   9321                 }
   9322                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   9323                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   9324                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
   9325                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   9326                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   9327                     return OMX_ErrorBadParameter;
   9328                 }
   9329                 frame_count++;
   9330                 pdest_frame = NULL;
   9331             } else {
   9332                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   9333                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   9334                 generate_ebd = OMX_FALSE;
   9335             }
   9336         }
   9337     }
   9338 
   9339     if (generate_ebd && !psource_frame->nFilledLen) {
   9340         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
   9341         psource_frame = NULL;
   9342         if (m_input_pending_q.m_size) {
   9343             m_input_pending_q.pop_entry(&address, &p2, &id);
   9344             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   9345             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
   9346                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
   9347         }
   9348     }
   9349     return OMX_ErrorNone;
   9350 }
   9351 
   9352 OMX_ERRORTYPE omx_vdec::push_input_vc1(OMX_HANDLETYPE hComp)
   9353 {
   9354     OMX_U8 *buf, *pdest;
   9355     OMX_U32 partial_frame = 1;
   9356     OMX_U32 buf_len, dest_len;
   9357 
   9358     if (first_frame == 0) {
   9359         first_frame = 1;
   9360         DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
   9361         if (!m_vendor_config.pData) {
   9362             DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
   9363             buf = psource_frame->pBuffer;
   9364             buf_len = psource_frame->nFilledLen;
   9365 
   9366             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   9367                     VC1_SP_MP_START_CODE) {
   9368                 m_vc1_profile = VC1_SP_MP_RCV;
   9369             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   9370                 m_vc1_profile = VC1_AP;
   9371             } else {
   9372                 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
   9373                 return OMX_ErrorStreamCorrupt;
   9374             }
   9375         } else {
   9376             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   9377                 pdest_frame->nOffset;
   9378             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   9379                     pdest_frame->nOffset);
   9380 
   9381             if (dest_len < m_vendor_config.nDataSize) {
   9382                 DEBUG_PRINT_ERROR("Destination buffer full");
   9383                 return OMX_ErrorBadParameter;
   9384             } else {
   9385                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   9386                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   9387             }
   9388         }
   9389     }
   9390 
   9391     switch (m_vc1_profile) {
   9392         case VC1_AP:
   9393             DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
   9394             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   9395                 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
   9396                 return OMX_ErrorBadParameter;
   9397             }
   9398             break;
   9399 
   9400         case VC1_SP_MP_RCV:
   9401         default:
   9402             DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
   9403             return OMX_ErrorBadParameter;
   9404     }
   9405     return OMX_ErrorNone;
   9406 }
   9407 
   9408 #ifndef USE_ION
   9409 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   9410         OMX_U32 alignment)
   9411 {
   9412     struct pmem_allocation allocation;
   9413     allocation.size = buffer_size;
   9414     allocation.align = clip2(alignment);
   9415     if (allocation.align < 4096) {
   9416         allocation.align = 4096;
   9417     }
   9418     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   9419         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
   9420                 allocation.align, allocation.size);
   9421         return false;
   9422     }
   9423     return true;
   9424 }
   9425 #endif
   9426 #ifdef USE_ION
   9427 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   9428         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   9429         struct ion_fd_data *fd_data, int flag)
   9430 {
   9431     int fd = -EINVAL;
   9432     int rc = -EINVAL;
   9433     int ion_dev_flag;
   9434     struct vdec_ion ion_buf_info;
   9435     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   9436         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
   9437         return -EINVAL;
   9438     }
   9439     ion_dev_flag = O_RDONLY;
   9440     fd = open (MEM_DEVICE, ion_dev_flag);
   9441     if (fd < 0) {
   9442         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
   9443         return fd;
   9444     }
   9445 
   9446     alloc_data->flags = flag;
   9447     alloc_data->len = buffer_size;
   9448     alloc_data->align = clip2(alignment);
   9449     if (alloc_data->align < 4096) {
   9450         alloc_data->align = 4096;
   9451     }
   9452 
   9453     alloc_data->heap_id_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
   9454     if (secure_mode && (alloc_data->flags & ION_SECURE)) {
   9455         alloc_data->heap_id_mask = ION_HEAP(MEM_HEAP_ID);
   9456     }
   9457 
   9458     /* Use secure display cma heap for obvious reasons. */
   9459     if (alloc_data->flags & ION_FLAG_CP_BITSTREAM) {
   9460         alloc_data->heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
   9461     }
   9462 
   9463     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   9464     if (rc || !alloc_data->handle) {
   9465         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
   9466         alloc_data->handle = 0;
   9467         close(fd);
   9468         fd = -ENOMEM;
   9469         return fd;
   9470     }
   9471     fd_data->handle = alloc_data->handle;
   9472     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   9473     if (rc) {
   9474         DEBUG_PRINT_ERROR("ION MAP failed ");
   9475         ion_buf_info.ion_alloc_data = *alloc_data;
   9476         ion_buf_info.ion_device_fd = fd;
   9477         ion_buf_info.fd_ion_data = *fd_data;
   9478         free_ion_memory(&ion_buf_info);
   9479         fd_data->fd =-1;
   9480         fd = -ENOMEM;
   9481     }
   9482 
   9483     return fd;
   9484 }
   9485 
   9486 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   9487 {
   9488 
   9489     if (!buf_ion_info) {
   9490         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
   9491         return;
   9492     }
   9493     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   9494                 &buf_ion_info->ion_alloc_data.handle)) {
   9495         DEBUG_PRINT_ERROR("ION: free failed" );
   9496     }
   9497     close(buf_ion_info->ion_device_fd);
   9498     buf_ion_info->ion_device_fd = -1;
   9499     buf_ion_info->ion_alloc_data.handle = 0;
   9500     buf_ion_info->fd_ion_data.fd = -1;
   9501 }
   9502 #endif
   9503 void omx_vdec::free_output_buffer_header()
   9504 {
   9505     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
   9506     output_use_buffer = false;
   9507     ouput_egl_buffers = false;
   9508 
   9509     if (m_out_mem_ptr) {
   9510         free (m_out_mem_ptr);
   9511         m_out_mem_ptr = NULL;
   9512     }
   9513 
   9514     if (m_platform_list) {
   9515         free(m_platform_list);
   9516         m_platform_list = NULL;
   9517     }
   9518 
   9519     if (drv_ctx.ptr_respbuffer) {
   9520         free (drv_ctx.ptr_respbuffer);
   9521         drv_ctx.ptr_respbuffer = NULL;
   9522     }
   9523     if (drv_ctx.ptr_outputbuffer) {
   9524         free (drv_ctx.ptr_outputbuffer);
   9525         drv_ctx.ptr_outputbuffer = NULL;
   9526     }
   9527 #ifdef USE_ION
   9528     if (drv_ctx.op_buf_ion_info) {
   9529         DEBUG_PRINT_LOW("Free o/p ion context");
   9530         free(drv_ctx.op_buf_ion_info);
   9531         drv_ctx.op_buf_ion_info = NULL;
   9532     }
   9533 #endif
   9534     buf_ref_remove();
   9535 }
   9536 
   9537 void omx_vdec::free_input_buffer_header()
   9538 {
   9539     input_use_buffer = false;
   9540     if (arbitrary_bytes) {
   9541         if (m_inp_heap_ptr) {
   9542             DEBUG_PRINT_LOW("Free input Heap Pointer");
   9543             free (m_inp_heap_ptr);
   9544             m_inp_heap_ptr = NULL;
   9545         }
   9546 
   9547         if (m_phdr_pmem_ptr) {
   9548             DEBUG_PRINT_LOW("Free input pmem header Pointer");
   9549             free (m_phdr_pmem_ptr);
   9550             m_phdr_pmem_ptr = NULL;
   9551         }
   9552     }
   9553     if (m_inp_mem_ptr) {
   9554         DEBUG_PRINT_LOW("Free input pmem Pointer area");
   9555         free (m_inp_mem_ptr);
   9556         m_inp_mem_ptr = NULL;
   9557     }
   9558     /* We just freed all the buffer headers, every thing in m_input_free_q,
   9559      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
   9560     while (m_input_free_q.m_size) {
   9561         unsigned long address, p2, id;
   9562         m_input_free_q.pop_entry(&address, &p2, &id);
   9563     }
   9564     while (m_input_pending_q.m_size) {
   9565         unsigned long address, p2, id;
   9566         m_input_pending_q.pop_entry(&address, &p2, &id);
   9567     }
   9568     pdest_frame = NULL;
   9569     psource_frame = NULL;
   9570     if (drv_ctx.ptr_inputbuffer) {
   9571         DEBUG_PRINT_LOW("Free Driver Context pointer");
   9572         free (drv_ctx.ptr_inputbuffer);
   9573         drv_ctx.ptr_inputbuffer = NULL;
   9574     }
   9575 #ifdef USE_ION
   9576     if (drv_ctx.ip_buf_ion_info) {
   9577         DEBUG_PRINT_LOW("Free ion context");
   9578         free(drv_ctx.ip_buf_ion_info);
   9579         drv_ctx.ip_buf_ion_info = NULL;
   9580     }
   9581 #endif
   9582 }
   9583 
   9584 int omx_vdec::stream_off(OMX_U32 port)
   9585 {
   9586     enum v4l2_buf_type btype;
   9587     int rc = 0;
   9588     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   9589 
   9590     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   9591         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9592         v4l2_port = OUTPUT_PORT;
   9593     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   9594         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9595         v4l2_port = CAPTURE_PORT;
   9596     } else if (port == OMX_ALL) {
   9597         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   9598         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   9599 
   9600         if (!rc_input)
   9601             return rc_input;
   9602         else
   9603             return rc_output;
   9604     }
   9605 
   9606     if (!streaming[v4l2_port]) {
   9607         // already streamed off, warn and move on
   9608         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   9609                 " which is already streamed off", v4l2_port);
   9610         return 0;
   9611     }
   9612 
   9613     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   9614 
   9615     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   9616     if (rc) {
   9617         /*TODO: How to handle this case */
   9618         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
   9619     } else {
   9620         streaming[v4l2_port] = false;
   9621     }
   9622 
   9623     return rc;
   9624 }
   9625 
   9626 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   9627 {
   9628     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9629     struct v4l2_requestbuffers bufreq;
   9630     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
   9631     unsigned int final_extra_data_size = 0;
   9632     struct v4l2_format fmt;
   9633     int ret = 0;
   9634     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   9635             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9636     bufreq.memory = V4L2_MEMORY_USERPTR;
   9637     bufreq.count = 1;
   9638     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9639         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9640         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9641         fmt.fmt.pix_mp.pixelformat = output_capability;
   9642     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9643         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9644         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9645         fmt.fmt.pix_mp.pixelformat = capture_capability;
   9646     } else {
   9647         eRet = OMX_ErrorBadParameter;
   9648     }
   9649     if (eRet==OMX_ErrorNone) {
   9650         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   9651     }
   9652     if (ret) {
   9653         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   9654         /*TODO: How to handle this case */
   9655         eRet = OMX_ErrorInsufficientResources;
   9656         return eRet;
   9657     } else {
   9658         buffer_prop->actualcount = bufreq.count;
   9659         buffer_prop->mincount = bufreq.count;
   9660         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
   9661     }
   9662     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   9663             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9664 
   9665     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   9666     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   9667 
   9668     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   9669 
   9670     update_resolution(fmt.fmt.pix_mp.width,
   9671             fmt.fmt.pix_mp.height,
   9672             fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
   9673             fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   9674     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   9675         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   9676     DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   9677 
   9678     if (ret) {
   9679         /*TODO: How to handle this case */
   9680         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   9681         eRet = OMX_ErrorInsufficientResources;
   9682     } else {
   9683         int extra_idx = 0;
   9684 
   9685         eRet = is_video_session_supported();
   9686         if (eRet)
   9687             return eRet;
   9688 
   9689         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   9690         buf_size = buffer_prop->buffer_size;
   9691         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   9692         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   9693             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   9694         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   9695             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   9696             return OMX_ErrorBadParameter;
   9697         }
   9698 
   9699         default_extra_data_size = VENUS_EXTRADATA_SIZE(
   9700                 drv_ctx.video_resolution.frame_height,
   9701                 drv_ctx.video_resolution.frame_width);
   9702         final_extra_data_size = extra_data_size > default_extra_data_size ?
   9703             extra_data_size : default_extra_data_size;
   9704 
   9705         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
   9706             (~(buffer_prop->alignment - 1));
   9707 
   9708         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
   9709         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   9710         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
   9711         if (!secure_mode)
   9712             buf_size += final_extra_data_size;
   9713         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   9714         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
   9715                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
   9716         if (extra_data_size)
   9717             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
   9718                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
   9719 
   9720         if (in_reconfig) // BufReq will be set to driver when port is disabled
   9721             buffer_prop->buffer_size = buf_size;
   9722         else if (buf_size != buffer_prop->buffer_size) {
   9723             buffer_prop->buffer_size = buf_size;
   9724             eRet = set_buffer_req(buffer_prop);
   9725         }
   9726     }
   9727     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
   9728             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9729     return eRet;
   9730 }
   9731 
   9732 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   9733 {
   9734     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9735     unsigned buf_size = 0;
   9736     struct v4l2_format fmt;
   9737     struct v4l2_requestbuffers bufreq;
   9738     int ret;
   9739     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
   9740             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   9741     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   9742     if (buf_size != buffer_prop->buffer_size) {
   9743         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
   9744                 (unsigned int)buffer_prop->buffer_size, buf_size);
   9745         eRet = OMX_ErrorBadParameter;
   9746     } else {
   9747         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   9748         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   9749         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   9750         fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   9751 
   9752         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9753             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9754             fmt.fmt.pix_mp.pixelformat = output_capability;
   9755         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9756             fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9757             fmt.fmt.pix_mp.pixelformat = capture_capability;
   9758         } else {
   9759             eRet = OMX_ErrorBadParameter;
   9760         }
   9761 
   9762         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   9763         if (ret) {
   9764             /*TODO: How to handle this case */
   9765             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   9766             eRet = OMX_ErrorInsufficientResources;
   9767         }
   9768 
   9769         bufreq.memory = V4L2_MEMORY_USERPTR;
   9770         bufreq.count = buffer_prop->actualcount;
   9771         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   9772             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9773         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   9774             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9775         } else {
   9776             eRet = OMX_ErrorBadParameter;
   9777         }
   9778 
   9779         if (eRet==OMX_ErrorNone) {
   9780             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   9781         }
   9782 
   9783         if (ret) {
   9784             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   9785             /*TODO: How to handle this case */
   9786             eRet = OMX_ErrorInsufficientResources;
   9787         } else if (bufreq.count < buffer_prop->actualcount) {
   9788             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   9789                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   9790                     buffer_prop->actualcount, bufreq.count);
   9791             eRet = OMX_ErrorInsufficientResources;
   9792         } else {
   9793             if (!client_buffers.update_buffer_req()) {
   9794                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   9795                 eRet = OMX_ErrorInsufficientResources;
   9796             }
   9797         }
   9798     }
   9799     return eRet;
   9800 }
   9801 
   9802 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   9803 {
   9804     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9805     return eRet;
   9806 }
   9807 
   9808 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   9809 {
   9810     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9811     struct v4l2_format fmt;
   9812     if (!portDefn) {
   9813         return OMX_ErrorBadParameter;
   9814     }
   9815     DEBUG_PRINT_LOW("omx_vdec::update_portdef");
   9816     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   9817     portDefn->nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   9818     portDefn->eDomain    = OMX_PortDomainVideo;
   9819     if (drv_ctx.frame_rate.fps_denominator > 0)
   9820         portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
   9821             drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
   9822     else {
   9823         DEBUG_PRINT_ERROR("Error: Divide by zero");
   9824         return OMX_ErrorBadParameter;
   9825     }
   9826     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   9827     if (0 == portDefn->nPortIndex) {
   9828         portDefn->eDir =  OMX_DirInput;
   9829         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   9830         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   9831         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   9832         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   9833         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   9834         portDefn->bEnabled   = m_inp_bEnabled;
   9835         portDefn->bPopulated = m_inp_bPopulated;
   9836 
   9837         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9838         fmt.fmt.pix_mp.pixelformat = output_capability;
   9839     } else if (1 == portDefn->nPortIndex) {
   9840         unsigned int buf_size = 0;
   9841         if (!client_buffers.update_buffer_req()) {
   9842             DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
   9843             return OMX_ErrorHardware;
   9844         }
   9845         if (!client_buffers.get_buffer_req(buf_size)) {
   9846             DEBUG_PRINT_ERROR("update buffer requirements");
   9847             return OMX_ErrorHardware;
   9848         }
   9849         portDefn->nBufferSize = buf_size;
   9850         portDefn->eDir =  OMX_DirOutput;
   9851         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   9852         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   9853         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   9854         portDefn->bEnabled   = m_out_bEnabled;
   9855         portDefn->bPopulated = m_out_bPopulated;
   9856         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   9857             DEBUG_PRINT_ERROR("Error in getting color format");
   9858             return OMX_ErrorHardware;
   9859         }
   9860         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   9861         fmt.fmt.pix_mp.pixelformat = capture_capability;
   9862     } else {
   9863         portDefn->eDir = OMX_DirMax;
   9864         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   9865                 (int)portDefn->nPortIndex);
   9866         eRet = OMX_ErrorBadPortIndex;
   9867     }
   9868     if (is_down_scalar_enabled) {
   9869         int ret = 0;
   9870         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   9871         if (ret) {
   9872             DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
   9873             return OMX_ErrorHardware;
   9874         } else {
   9875             portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
   9876             portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
   9877             portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
   9878             portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
   9879         }
   9880     } else {
   9881         portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   9882         portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   9883         portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   9884         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   9885     }
   9886 
   9887     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
   9888        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
   9889            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
   9890            portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
   9891     }
   9892     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
   9893             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
   9894             (unsigned int)portDefn->nPortIndex,
   9895             (unsigned int)portDefn->format.video.nFrameWidth,
   9896             (unsigned int)portDefn->format.video.nFrameHeight,
   9897             (int)portDefn->format.video.nStride,
   9898             (unsigned int)portDefn->format.video.nSliceHeight,
   9899             (unsigned int)portDefn->format.video.eColorFormat,
   9900             (unsigned int)portDefn->nBufferSize,
   9901             (unsigned int)portDefn->nBufferCountActual);
   9902 
   9903     return eRet;
   9904 }
   9905 
   9906 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   9907 {
   9908     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9909     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   9910     unsigned i= 0;
   9911 
   9912     if (!m_out_mem_ptr) {
   9913         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
   9914         int nBufHdrSize        = 0;
   9915         int nPlatformEntrySize = 0;
   9916         int nPlatformListSize  = 0;
   9917         int nPMEMInfoSize = 0;
   9918         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   9919         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   9920         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   9921 
   9922         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
   9923                 drv_ctx.op_buf.actualcount);
   9924         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   9925             sizeof(OMX_BUFFERHEADERTYPE);
   9926 
   9927         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   9928             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   9929         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   9930             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   9931         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   9932             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   9933 
   9934         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   9935                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   9936                 nPMEMInfoSize,
   9937                 nPlatformListSize);
   9938         DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
   9939                 m_out_bm_count);
   9940         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   9941         // Alloc mem for platform specific info
   9942         char *pPtr=NULL;
   9943         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   9944                 nPMEMInfoSize,1);
   9945         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   9946                        calloc (sizeof(struct vdec_bufferpayload),
   9947                                drv_ctx.op_buf.actualcount);
   9948         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   9949                      calloc (sizeof (struct vdec_output_frameinfo),
   9950                              drv_ctx.op_buf.actualcount);
   9951         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   9952             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
   9953             return OMX_ErrorInsufficientResources;
   9954         }
   9955 
   9956 #ifdef USE_ION
   9957         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   9958                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   9959         if (!drv_ctx.op_buf_ion_info) {
   9960             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   9961             return OMX_ErrorInsufficientResources;
   9962         }
   9963 #endif
   9964         if (dynamic_buf_mode) {
   9965             out_dynamic_list = (struct dynamic_buf_list *) \
   9966                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   9967             if (out_dynamic_list) {
   9968                for (unsigned int i = 0; i < drv_ctx.op_buf.actualcount; i++)
   9969                   out_dynamic_list[i].dup_fd = -1;
   9970             }
   9971         }
   9972 
   9973         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   9974                 && drv_ctx.ptr_respbuffer) {
   9975             bufHdr          =  m_out_mem_ptr;
   9976             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   9977             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   9978                 (((char *) m_platform_list)  + nPlatformListSize);
   9979             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   9980                 (((char *) m_platform_entry) + nPlatformEntrySize);
   9981             pPlatformList   = m_platform_list;
   9982             pPlatformEntry  = m_platform_entry;
   9983             pPMEMInfo       = m_pmem_info;
   9984 
   9985             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   9986 
   9987             // Settting the entire storage nicely
   9988             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
   9989                     m_out_mem_ptr,pPlatformEntry);
   9990             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   9991             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   9992                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   9993                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   9994                 // Set the values when we determine the right HxW param
   9995                 bufHdr->nAllocLen          = 0;
   9996                 bufHdr->nFilledLen         = 0;
   9997                 bufHdr->pAppPrivate        = NULL;
   9998                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   9999                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   10000                 pPlatformEntry->entry      = pPMEMInfo;
   10001                 // Initialize the Platform List
   10002                 pPlatformList->nEntries    = 1;
   10003                 pPlatformList->entryList   = pPlatformEntry;
   10004                 // Keep pBuffer NULL till vdec is opened
   10005                 bufHdr->pBuffer            = NULL;
   10006                 pPMEMInfo->offset          =  0;
   10007                 pPMEMInfo->pmem_fd = -1;
   10008                 bufHdr->pPlatformPrivate = pPlatformList;
   10009                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   10010 #ifdef USE_ION
   10011                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   10012 #endif
   10013                 /*Create a mapping between buffers*/
   10014                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   10015                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   10016                                     &drv_ctx.ptr_outputbuffer[i];
   10017                 // Move the buffer and buffer header pointers
   10018                 bufHdr++;
   10019                 pPMEMInfo++;
   10020                 pPlatformEntry++;
   10021                 pPlatformList++;
   10022             }
   10023         } else {
   10024             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   10025                     m_out_mem_ptr, pPtr);
   10026             if (m_out_mem_ptr) {
   10027                 free(m_out_mem_ptr);
   10028                 m_out_mem_ptr = NULL;
   10029             }
   10030             if (pPtr) {
   10031                 free(pPtr);
   10032                 pPtr = NULL;
   10033             }
   10034             if (drv_ctx.ptr_outputbuffer) {
   10035                 free(drv_ctx.ptr_outputbuffer);
   10036                 drv_ctx.ptr_outputbuffer = NULL;
   10037             }
   10038             if (drv_ctx.ptr_respbuffer) {
   10039                 free(drv_ctx.ptr_respbuffer);
   10040                 drv_ctx.ptr_respbuffer = NULL;
   10041             }
   10042 #ifdef USE_ION
   10043             if (drv_ctx.op_buf_ion_info) {
   10044                 DEBUG_PRINT_LOW("Free o/p ion context");
   10045                 free(drv_ctx.op_buf_ion_info);
   10046                 drv_ctx.op_buf_ion_info = NULL;
   10047             }
   10048 #endif
   10049             eRet =  OMX_ErrorInsufficientResources;
   10050         }
   10051     } else {
   10052         eRet =  OMX_ErrorInsufficientResources;
   10053     }
   10054     return eRet;
   10055 }
   10056 
   10057 void omx_vdec::complete_pending_buffer_done_cbs()
   10058 {
   10059     unsigned long p1, p2, ident;
   10060     omx_cmd_queue tmp_q, pending_bd_q;
   10061     pthread_mutex_lock(&m_lock);
   10062     // pop all pending GENERATE FDB from ftb queue
   10063     while (m_ftb_q.m_size) {
   10064         m_ftb_q.pop_entry(&p1,&p2,&ident);
   10065         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   10066             pending_bd_q.insert_entry(p1,p2,ident);
   10067         } else {
   10068             tmp_q.insert_entry(p1,p2,ident);
   10069         }
   10070     }
   10071     //return all non GENERATE FDB to ftb queue
   10072     while (tmp_q.m_size) {
   10073         tmp_q.pop_entry(&p1,&p2,&ident);
   10074         m_ftb_q.insert_entry(p1,p2,ident);
   10075     }
   10076     // pop all pending GENERATE EDB from etb queue
   10077     while (m_etb_q.m_size) {
   10078         m_etb_q.pop_entry(&p1,&p2,&ident);
   10079         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   10080             pending_bd_q.insert_entry(p1,p2,ident);
   10081         } else {
   10082             tmp_q.insert_entry(p1,p2,ident);
   10083         }
   10084     }
   10085     //return all non GENERATE FDB to etb queue
   10086     while (tmp_q.m_size) {
   10087         tmp_q.pop_entry(&p1,&p2,&ident);
   10088         m_etb_q.insert_entry(p1,p2,ident);
   10089     }
   10090     pthread_mutex_unlock(&m_lock);
   10091     // process all pending buffer dones
   10092     while (pending_bd_q.m_size) {
   10093         pending_bd_q.pop_entry(&p1,&p2,&ident);
   10094         switch (ident) {
   10095             case OMX_COMPONENT_GENERATE_EBD:
   10096                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   10097                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   10098                     omx_report_error ();
   10099                 }
   10100                 break;
   10101 
   10102             case OMX_COMPONENT_GENERATE_FBD:
   10103                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   10104                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   10105                     omx_report_error ();
   10106                 }
   10107                 break;
   10108         }
   10109     }
   10110 }
   10111 
   10112 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   10113 {
   10114     OMX_U32 new_frame_interval = 0;
   10115     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   10116             && llabs(act_timestamp - prev_ts) > 2000) {
   10117         new_frame_interval = client_set_fps ? frm_int : (act_timestamp - prev_ts) > 0 ?
   10118             llabs(act_timestamp - prev_ts) : llabs(act_timestamp - prev_ts_actual);
   10119         if (new_frame_interval != frm_int || frm_int == 0) {
   10120             frm_int = new_frame_interval;
   10121             if (frm_int) {
   10122                 drv_ctx.frame_rate.fps_numerator = 1e6;
   10123                 drv_ctx.frame_rate.fps_denominator = frm_int;
   10124                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
   10125                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   10126                         (float)drv_ctx.frame_rate.fps_denominator);
   10127                 m_perf_control.request_cores(frm_int);
   10128                 /* We need to report the difference between this FBD and the previous FBD
   10129                  * back to the driver for clock scaling purposes. */
   10130                 struct v4l2_outputparm oparm;
   10131                 /*XXX: we're providing timing info as seconds per frame rather than frames
   10132                  * per second.*/
   10133                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   10134                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   10135 
   10136                 struct v4l2_streamparm sparm;
   10137                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10138                 sparm.parm.output = oparm;
   10139                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   10140                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   10141                             performance might be affected");
   10142                 }
   10143 
   10144             }
   10145         }
   10146     }
   10147     prev_ts = act_timestamp;
   10148 }
   10149 
   10150 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   10151 {
   10152     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   10153         prev_ts = act_timestamp;
   10154         prev_ts_actual = act_timestamp;
   10155         rst_prev_ts = false;
   10156     } else if (VALID_TS(prev_ts)) {
   10157         bool codec_cond = (drv_ctx.timestamp_adjust)?
   10158             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts_actual || llabs(act_timestamp - prev_ts_actual) <= 2000) :
   10159             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts_actual);
   10160              prev_ts_actual = act_timestamp; //unadjusted previous timestamp
   10161         if (frm_int > 0 && codec_cond) {
   10162             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   10163             act_timestamp = prev_ts + frm_int;
   10164             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   10165             prev_ts = act_timestamp;
   10166         } else {
   10167             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
   10168                 // ensure that timestamps can never step backwards when in display order
   10169                 act_timestamp = prev_ts;
   10170             }
   10171             set_frame_rate(act_timestamp);
   10172         }
   10173     } else if (frm_int > 0)          // In this case the frame rate was set along
   10174     {                               // with the port definition, start ts with 0
   10175         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   10176         rst_prev_ts = true;
   10177     }
   10178 }
   10179 
   10180 void omx_vdec::convert_color_space_info(OMX_U32 primaries, OMX_U32 range,
   10181     OMX_U32 transfer, OMX_U32 matrix, ColorSpace_t *color_space, ColorAspects *aspects)
   10182 {
   10183     switch (primaries) {
   10184         case MSM_VIDC_BT709_5:
   10185             *color_space = ITU_R_709;
   10186             aspects->mPrimaries = ColorAspects::PrimariesBT709_5;
   10187             break;
   10188         case MSM_VIDC_BT470_6_M:
   10189             aspects->mPrimaries = ColorAspects::PrimariesBT470_6M;
   10190             break;
   10191         case MSM_VIDC_BT601_6_625:
   10192             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10193             break;
   10194         case MSM_VIDC_BT601_6_525:
   10195             *color_space = range ? ITU_R_601_FR : ITU_R_601;
   10196             aspects->mPrimaries = ColorAspects::PrimariesBT601_6_525;
   10197             break;
   10198         case MSM_VIDC_GENERIC_FILM:
   10199             aspects->mPrimaries = ColorAspects::PrimariesGenericFilm;
   10200             break;
   10201         case MSM_VIDC_BT2020:
   10202             aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   10203             break;
   10204         case MSM_VIDC_UNSPECIFIED:
   10205             //Client does not expect ColorAspects::PrimariesUnspecified, but rather the supplied default
   10206         default:
   10207             //aspects->mPrimaries = ColorAspects::PrimariesOther;
   10208             aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10209             break;
   10210     }
   10211 
   10212     aspects->mRange = range ? ColorAspects::RangeFull : ColorAspects::RangeLimited;
   10213 
   10214     switch (transfer) {
   10215         case MSM_VIDC_TRANSFER_BT709_5:
   10216         case MSM_VIDC_TRANSFER_601_6_525: // case MSM_VIDC_TRANSFER_601_6_625:
   10217             aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10218             break;
   10219         case MSM_VIDC_TRANSFER_BT_470_6_M:
   10220             aspects->mTransfer = ColorAspects::TransferGamma22;
   10221             break;
   10222         case MSM_VIDC_TRANSFER_BT_470_6_BG:
   10223             aspects->mTransfer = ColorAspects::TransferGamma28;
   10224             break;
   10225         case MSM_VIDC_TRANSFER_SMPTE_240M:
   10226             aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   10227             break;
   10228         case MSM_VIDC_TRANSFER_LINEAR:
   10229             aspects->mTransfer = ColorAspects::TransferLinear;
   10230             break;
   10231         case MSM_VIDC_TRANSFER_IEC_61966:
   10232             aspects->mTransfer = ColorAspects::TransferXvYCC;
   10233             break;
   10234         case MSM_VIDC_TRANSFER_BT_1361:
   10235             aspects->mTransfer = ColorAspects::TransferBT1361;
   10236             break;
   10237         case MSM_VIDC_TRANSFER_SRGB:
   10238             aspects->mTransfer = ColorAspects::TransferSRGB;
   10239             break;
   10240         default:
   10241             //aspects->mTransfer = ColorAspects::TransferOther;
   10242             aspects->mTransfer = m_client_color_space.sAspects.mTransfer;
   10243             break;
   10244     }
   10245 
   10246     switch (matrix) {
   10247         case MSM_VIDC_MATRIX_BT_709_5:
   10248             aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10249             break;
   10250         case MSM_VIDC_MATRIX_FCC_47:
   10251             aspects->mMatrixCoeffs = ColorAspects::MatrixBT470_6M;
   10252             break;
   10253         case MSM_VIDC_MATRIX_601_6_625:
   10254         case MSM_VIDC_MATRIX_601_6_525:
   10255             aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   10256             break;
   10257         case MSM_VIDC_MATRIX_SMPTE_240M:
   10258             aspects->mMatrixCoeffs = ColorAspects::MatrixSMPTE240M;
   10259             break;
   10260         case MSM_VIDC_MATRIX_BT_2020:
   10261             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   10262             break;
   10263         case MSM_VIDC_MATRIX_BT_2020_CONST:
   10264             aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020Constant;
   10265             break;
   10266         default:
   10267             //aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   10268             aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   10269             break;
   10270     }
   10271 }
   10272 
   10273 void omx_vdec::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
   10274         DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
   10275                 prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
   10276 }
   10277 
   10278 void omx_vdec::handle_color_space_info(void *data, unsigned int buf_index)
   10279 {
   10280     ColorSpace_t color_space = ITU_R_601;
   10281     ColorAspects tempAspects;
   10282     memset(&tempAspects, 0x0, sizeof(ColorAspects));
   10283     ColorAspects *aspects = &tempAspects;
   10284 
   10285     switch(output_capability) {
   10286         case V4L2_PIX_FMT_MPEG2:
   10287             {
   10288                 struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   10289                 seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)data;
   10290 
   10291                 /* Refer MPEG2 Spec @ Rec. ISO/IEC 13818-2, ITU-T Draft Rec. H.262 to
   10292                  * understand this code */
   10293 
   10294                 if (seqdisp_payload && seqdisp_payload->color_descp) {
   10295 
   10296                     convert_color_space_info(seqdisp_payload->color_primaries, 1,
   10297                             seqdisp_payload->transfer_char, seqdisp_payload->matrix_coeffs,
   10298                             &color_space,aspects);
   10299                     m_disp_hor_size = seqdisp_payload->disp_width;
   10300                     m_disp_vert_size = seqdisp_payload->disp_height;
   10301                 }
   10302             }
   10303             break;
   10304         case V4L2_PIX_FMT_H264:
   10305         case V4L2_PIX_FMT_HEVC:
   10306             {
   10307                 struct msm_vidc_vui_display_info_payload *display_info_payload;
   10308                 display_info_payload = (struct msm_vidc_vui_display_info_payload*)data;
   10309 
   10310                 /* Refer H264 Spec @ Rec. ITU-T H.264 (02/2014) to understand this code */
   10311 
   10312                 if (display_info_payload->video_signal_present_flag &&
   10313                         display_info_payload->color_description_present_flag) {
   10314                     convert_color_space_info(display_info_payload->color_primaries,
   10315                             display_info_payload->video_full_range_flag,
   10316                             display_info_payload->transfer_characteristics,
   10317                             display_info_payload->matrix_coefficients,
   10318                             &color_space,aspects);
   10319                 }
   10320             }
   10321             break;
   10322         case V4L2_PIX_FMT_VC1_ANNEX_G:
   10323         case V4L2_PIX_FMT_VC1_ANNEX_L:
   10324             {
   10325                 struct msm_vidc_vc1_seqdisp_payload *vc1_seq_disp_payload;
   10326                 vc1_seq_disp_payload = (struct msm_vidc_vc1_seqdisp_payload*)data;
   10327 
   10328                 /* Refer VC-1 Spec @ SMPTE Draft Standard for Television Date: 2005-08-23
   10329                  * SMPTE 421M to understand this code */
   10330 
   10331                 if (m_enable_android_native_buffers &&
   10332                         vc1_seq_disp_payload->color_primaries) {
   10333 
   10334                     convert_color_space_info(vc1_seq_disp_payload->color_primaries,
   10335                             1,
   10336                             vc1_seq_disp_payload->transfer_char,
   10337                             vc1_seq_disp_payload->matrix_coeffs,
   10338                             &color_space,aspects);
   10339                 }
   10340             }
   10341             break;
   10342         case V4L2_PIX_FMT_VP8:
   10343             {
   10344                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   10345                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   10346 
   10347                 /* Refer VP8 Data Format in latest VP8 spec and Decoding Guide November 2011
   10348                  * to understand this code */
   10349 
   10350                 if (vpx_color_space_payload->color_space == 0) {
   10351                     color_space = ITU_R_601;
   10352                 } else {
   10353                     DEBUG_PRINT_ERROR("Unsupported Color space for VP8");
   10354                     break;
   10355                 }
   10356             }
   10357             break;
   10358         case V4L2_PIX_FMT_VP9:
   10359             {
   10360                 struct msm_vidc_vpx_colorspace_payload *vpx_color_space_payload;
   10361                 vpx_color_space_payload = (struct msm_vidc_vpx_colorspace_payload*)data;
   10362 
   10363                 /* Refer VP9 Spec @ VP9 Bitstream & Decoding Process Specification - v0.6 31st March 2016
   10364                  * to understand this code */
   10365 
   10366                 switch(vpx_color_space_payload->color_space) {
   10367                     case MSM_VIDC_CS_BT_601:
   10368                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT601_6;
   10369                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10370                         aspects->mPrimaries = ColorAspects::PrimariesBT601_6_625;
   10371                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10372                         break;
   10373                     case MSM_VIDC_CS_BT_709:
   10374                         color_space = ITU_R_709;
   10375                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10376                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10377                         aspects->mPrimaries =  ColorAspects::PrimariesBT709_5;
   10378                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10379                         break;
   10380                     case MSM_VIDC_CS_SMPTE_170:
   10381                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10382                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10383                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10384                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10385                         break;
   10386                     case MSM_VIDC_CS_SMPTE_240:
   10387                         aspects->mMatrixCoeffs = m_client_color_space.sAspects.mMatrixCoeffs;
   10388                         aspects->mTransfer = ColorAspects::TransferSMPTE240M;
   10389                         aspects->mPrimaries = m_client_color_space.sAspects.mPrimaries;
   10390                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10391                         break;
   10392                     case MSM_VIDC_CS_BT_2020:
   10393                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT2020;
   10394                         aspects->mTransfer = ColorAspects:: TransferSMPTE170M;
   10395                         aspects->mPrimaries = ColorAspects::PrimariesBT2020;
   10396                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10397                         break;
   10398                     case MSM_VIDC_CS_RESERVED:
   10399                         aspects->mMatrixCoeffs = ColorAspects::MatrixOther;
   10400                         aspects->mTransfer = ColorAspects::TransferOther;
   10401                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   10402                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10403                         break;
   10404                     case MSM_VIDC_CS_RGB:
   10405                         aspects->mMatrixCoeffs = ColorAspects::MatrixBT709_5;
   10406                         aspects->mTransfer = ColorAspects::TransferSMPTE170M;
   10407                         aspects->mPrimaries = ColorAspects::PrimariesOther;
   10408                         aspects->mRange = m_client_color_space.sAspects.mRange;
   10409                         break;
   10410                     default:
   10411                         break;
   10412                 }
   10413             }
   10414             break;
   10415         default:
   10416             break;
   10417     }
   10418     if (m_enable_android_native_buffers) {
   10419         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);
   10420         set_colorspace_in_handle(color_space, buf_index);
   10421     }
   10422     print_debug_color_aspects(aspects, "Bitstream");
   10423 
   10424     if (m_internal_color_space.sAspects.mPrimaries != aspects->mPrimaries ||
   10425             m_internal_color_space.sAspects.mTransfer != aspects->mTransfer ||
   10426             m_internal_color_space.sAspects.mMatrixCoeffs != aspects->mMatrixCoeffs ||
   10427             m_internal_color_space.sAspects.mRange != aspects->mRange) {
   10428         memcpy(&(m_internal_color_space.sAspects), aspects, sizeof(ColorAspects));
   10429         m_internal_color_space.bDataSpaceChanged = OMX_TRUE;
   10430 
   10431         DEBUG_PRINT_HIGH("Initiating PORT Reconfig");
   10432         print_debug_color_aspects(&(m_internal_color_space.sAspects), "Internal");
   10433         print_debug_color_aspects(&(m_client_color_space.sAspects), "Client");
   10434 
   10435         post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   10436                 OMX_QTIIndexConfigDescribeColorAspects,
   10437                 OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   10438     }
   10439 }
   10440 
   10441 void omx_vdec::set_colorspace_in_handle(ColorSpace_t color_space, unsigned int buf_index) {
   10442     private_handle_t *private_handle = NULL;
   10443     if (buf_index < drv_ctx.op_buf.actualcount &&
   10444             buf_index < MAX_NUM_INPUT_OUTPUT_BUFFERS &&
   10445             native_buffer[buf_index].privatehandle) {
   10446         private_handle = native_buffer[buf_index].privatehandle;
   10447     }
   10448     if (private_handle) {
   10449         setMetaData(private_handle, UPDATE_COLOR_SPACE, (void*)&color_space);
   10450     }
   10451 }
   10452 
   10453 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   10454 {
   10455     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
   10456     OMX_U32 num_conceal_MB = 0;
   10457     OMX_TICKS time_stamp = 0;
   10458     OMX_U32 frame_rate = 0;
   10459     unsigned long consumed_len = 0;
   10460     OMX_U32 num_MB_in_frame;
   10461     OMX_U32 recovery_sei_flags = 1;
   10462     int enable = 0;
   10463 
   10464     int buf_index = p_buf_hdr - m_out_mem_ptr;
   10465     if (buf_index >= drv_ctx.extradata_info.count) {
   10466         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   10467                 buf_index, drv_ctx.extradata_info.count);
   10468         return;
   10469     }
   10470     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   10471 
   10472     if (drv_ctx.ptr_outputbuffer[buf_index].bufferaddr == NULL) {
   10473         DEBUG_PRINT_ERROR("handle_extradata: Error: Mapped output buffer address is NULL");
   10474         return;
   10475     }
   10476 
   10477     OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
   10478         p_buf_hdr->nOffset;
   10479 
   10480     if (!drv_ctx.extradata_info.uaddr) {
   10481         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
   10482         return;
   10483     }
   10484     if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
   10485         DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
   10486         p_extra = NULL;
   10487         return;
   10488     }
   10489     if (!secure_mode)
   10490         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   10491             ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   10492     else
   10493         p_extra = m_other_extradata;
   10494     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   10495 
   10496     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   10497         p_extra = NULL;
   10498         DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   10499         return;
   10500     }
   10501     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   10502     if (data && p_extra) {
   10503         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   10504                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
   10505             if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
   10506                 DEBUG_PRINT_LOW("Invalid extra data size");
   10507                 break;
   10508             }
   10509 
   10510             if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   10511                 p_extra = NULL;
   10512                 DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   10513                 return;
   10514             }
   10515 
   10516             DEBUG_PRINT_LOW("handle_extradata: eType = 0x%x", data->eType);
   10517             switch ((unsigned long)data->eType) {
   10518                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
   10519                     struct msm_vidc_interlace_payload *payload;
   10520                     OMX_U32 interlace_color_format;
   10521                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
   10522                     if (payload) {
   10523                         enable = 1;
   10524                         switch (payload->format) {
   10525                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
   10526                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   10527                                 enable = 0;
   10528                                 break;
   10529                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
   10530                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   10531                                 break;
   10532                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
   10533                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   10534                                 break;
   10535                             default:
   10536                                 DEBUG_PRINT_LOW("default case - set interlace to topfield");
   10537                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   10538                         }
   10539                         switch (payload->color_format) {
   10540                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12:
   10541                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10542                                drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   10543                                break;
   10544                            case MSM_VIDC_HAL_INTERLACE_COLOR_FORMAT_NV12_UBWC:
   10545                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   10546                                drv_ctx.output_format = VDEC_YUV_FORMAT_NV12_UBWC;
   10547                                break;
   10548                            default:
   10549                                interlace_color_format = (int)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10550                                DEBUG_PRINT_ERROR("Error - Unknown color format hint for interlaced frame");
   10551                         }
   10552                     }
   10553 
   10554                     if (m_enable_android_native_buffers) {
   10555                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d color_format: %x enable:%d mbaff:%d",
   10556                                          payload->format, interlace_color_format ,enable,
   10557                                         (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
   10558 
   10559                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   10560                                PP_PARAM_INTERLACED, (void*)&enable);
   10561 
   10562                         if (interlace_color_format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m) {
   10563                             setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   10564                                LINEAR_FORMAT, (void*)&interlace_color_format);
   10565                         }
   10566                     }
   10567                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   10568                         append_interlace_extradata(p_extra, payload->format,
   10569                                       p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
   10570                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10571                     }
   10572                     break;
   10573                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
   10574                     struct msm_vidc_framerate_payload *frame_rate_payload;
   10575                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
   10576                     frame_rate = frame_rate_payload->frame_rate;
   10577                     break;
   10578                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
   10579                     struct msm_vidc_ts_payload *time_stamp_payload;
   10580                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
   10581                     time_stamp = time_stamp_payload->timestamp_lo;
   10582                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   10583                     p_buf_hdr->nTimeStamp = time_stamp;
   10584                     break;
   10585                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
   10586                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   10587                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
   10588                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   10589                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   10590                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   10591                     break;
   10592                 case MSM_VIDC_EXTRADATA_INDEX:
   10593                     int *etype;
   10594                     etype  = (int *)(void *)data->data;
   10595                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
   10596                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   10597                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   10598                         if (aspect_ratio_payload) {
   10599                             ((struct vdec_output_frameinfo *)
   10600                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   10601                             ((struct vdec_output_frameinfo *)
   10602                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   10603                         }
   10604                     }
   10605                     break;
   10606                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
   10607                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   10608                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
   10609                     recovery_sei_flags = recovery_sei_payload->flags;
   10610                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
   10611                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   10612                         DEBUG_PRINT_HIGH("***************************************************");
   10613                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   10614                         DEBUG_PRINT_HIGH("***************************************************");
   10615                     }
   10616                     break;
   10617                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
   10618                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
   10619                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
   10620                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
   10621                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
   10622                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
   10623                         return;
   10624                     }
   10625                     break;
   10626                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
   10627                 case MSM_VIDC_EXTRADATA_VUI_DISPLAY_INFO:
   10628                 case MSM_VIDC_EXTRADATA_VC1_SEQDISP:
   10629                 case MSM_VIDC_EXTRADATA_VPX_COLORSPACE_INFO:
   10630                         handle_color_space_info((void *)data->data, buf_index);
   10631                     break;
   10632                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
   10633                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
   10634                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
   10635                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
   10636                         append_framepack_extradata(p_extra, s3d_frame_packing_payload);
   10637                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10638                     }
   10639                     break;
   10640                 case MSM_VIDC_EXTRADATA_FRAME_QP:
   10641                     struct msm_vidc_frame_qp_payload *qp_payload;
   10642                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
   10643                     if (client_extradata & OMX_QP_EXTRADATA) {
   10644                         append_qp_extradata(p_extra, qp_payload);
   10645                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10646                     }
   10647                     break;
   10648                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
   10649                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
   10650                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
   10651                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
   10652                         append_bitsinfo_extradata(p_extra, bits_info_payload);
   10653                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10654                     }
   10655                     break;
   10656                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
   10657                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
   10658                         append_user_extradata(p_extra, data);
   10659                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10660                     }
   10661                     break;
   10662                 case MSM_VIDC_EXTRADATA_VQZIP_SEI:
   10663                     struct msm_vidc_vqzip_sei_payload *vqzip_payload;
   10664                     vqzip_payload = (struct msm_vidc_vqzip_sei_payload*)(void *)data->data;
   10665                     if (client_extradata & OMX_VQZIPSEI_EXTRADATA) {
   10666                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10667                         append_vqzip_extradata(p_extra, vqzip_payload);
   10668                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10669                     }
   10670                     break;
   10671                 default:
   10672                     DEBUG_PRINT_LOW("Unrecognized extradata");
   10673                     goto unrecognized_extradata;
   10674             }
   10675             consumed_len += data->nSize;
   10676             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   10677         }
   10678         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   10679             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10680             append_frame_info_extradata(p_extra,
   10681                     num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   10682                     time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   10683                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   10684             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10685         }
   10686         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
   10687             append_frame_dimension_extradata(p_extra);
   10688             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   10689         }
   10690     }
   10691 unrecognized_extradata:
   10692     if (client_extradata && p_extra) {
   10693         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   10694         append_terminator_extradata(p_extra);
   10695     }
   10696     if (secure_mode && p_extradata && m_other_extradata) {
   10697         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
   10698         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
   10699         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
   10700         ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
   10701         ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
   10702     }
   10703     return;
   10704 }
   10705 
   10706 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
   10707         bool is_internal, bool enable)
   10708 {
   10709     OMX_ERRORTYPE ret = OMX_ErrorNone;
   10710     struct v4l2_control control;
   10711     if (m_state != OMX_StateLoaded) {
   10712         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   10713         return OMX_ErrorIncorrectStateOperation;
   10714     }
   10715     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
   10716             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
   10717 
   10718     if (!is_internal) {
   10719         if (enable)
   10720             client_extradata |= requested_extradata;
   10721         else
   10722             client_extradata = client_extradata & ~requested_extradata;
   10723     }
   10724 
   10725     if (enable) {
   10726         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   10727             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10728             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   10729             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10730                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   10731                         " Quality of interlaced clips might be impacted.");
   10732             }
   10733         }
   10734         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   10735             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10736             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   10737             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10738                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
   10739             }
   10740             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10741             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   10742             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10743                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
   10744             }
   10745             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10746             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   10747             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10748                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
   10749             }
   10750             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10751             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   10752             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10753                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10754             }
   10755             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10756             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
   10757             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10758                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10759             }
   10760             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   10761                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10762                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   10763                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10764                     DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   10765                 }
   10766             }
   10767         }
   10768         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   10769             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10770             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   10771             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10772                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
   10773             }
   10774         }
   10775         if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
   10776             if (output_capability == V4L2_PIX_FMT_H264) {
   10777                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
   10778                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10779                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
   10780                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10781                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
   10782                 }
   10783             } else {
   10784                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
   10785             }
   10786         }
   10787         if (requested_extradata & OMX_QP_EXTRADATA) {
   10788             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10789             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   10790             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10791                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   10792             }
   10793         }
   10794         if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
   10795             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10796             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
   10797             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10798                 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
   10799             }
   10800         }
   10801         if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
   10802             if (secure_mode) {
   10803                 DEBUG_PRINT_HIGH("ExtnUser Extra Data not supported for secure sessions");
   10804                 return OMX_ErrorUnsupportedSetting;
   10805             }
   10806             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10807             control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
   10808             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10809                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
   10810             }
   10811         }
   10812         if (requested_extradata & OMX_VQZIPSEI_EXTRADATA) {
   10813             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10814             control.value = V4L2_MPEG_VIDC_EXTRADATA_VQZIP_SEI;
   10815             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10816                 DEBUG_PRINT_HIGH("Failed to set VQZip SEI extradata");
   10817             }
   10818             client_extradata |= OMX_VQZIPSEI_EXTRADATA;
   10819 
   10820             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10821             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   10822             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10823                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   10824             }
   10825             client_extradata |= OMX_QP_EXTRADATA;
   10826         }
   10827         if (requested_extradata & OMX_DISPLAY_INFO_EXTRADATA) {
   10828             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   10829             switch(output_capability) {
   10830                 case V4L2_PIX_FMT_H264:
   10831                 case V4L2_PIX_FMT_HEVC:
   10832                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_VUI_DISPLAY;
   10833                     break;
   10834                 case CODEC_TYPE_MPEG2:
   10835                     control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   10836                     break;
   10837                 case V4L2_PIX_FMT_VP8:
   10838                 case V4L2_PIX_FMT_VP9:
   10839                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VPX_COLORSPACE;
   10840                     break;
   10841                 case V4L2_PIX_FMT_VC1_ANNEX_G:
   10842                 case V4L2_PIX_FMT_VC1_ANNEX_L:
   10843                     control.value = V4L2_MPEG_VIDC_EXTRADATA_VC1_SEQDISP;
   10844                     break;
   10845                 default:
   10846                     DEBUG_PRINT_HIGH("Don't support Disp info for this codec : %s", drv_ctx.kind);
   10847                     return ret;
   10848             }
   10849 
   10850             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   10851                 DEBUG_PRINT_HIGH("Failed to set Display info extradata");
   10852             }
   10853         }
   10854     }
   10855     ret = get_buffer_req(&drv_ctx.op_buf);
   10856     return ret;
   10857 }
   10858 
   10859 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   10860 {
   10861     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   10862     OMX_U8 *data_ptr = extra->data, data = 0;
   10863     while (byte_count < extra->nDataSize) {
   10864         data = *data_ptr;
   10865         while (data) {
   10866             num_MB += (data&0x01);
   10867             data >>= 1;
   10868         }
   10869         data_ptr++;
   10870         byte_count++;
   10871     }
   10872     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   10873             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   10874     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   10875 }
   10876 
   10877 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   10878 {
   10879     if (!m_debug_extradata || !extra)
   10880         return;
   10881 
   10882 
   10883     DEBUG_PRINT_HIGH(
   10884             "============== Extra Data ==============\n"
   10885             "           Size: %u\n"
   10886             "        Version: %u\n"
   10887             "      PortIndex: %u\n"
   10888             "           Type: %x\n"
   10889             "       DataSize: %u",
   10890             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
   10891             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
   10892 
   10893     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   10894         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   10895         DEBUG_PRINT_HIGH(
   10896                 "------ Interlace Format ------\n"
   10897                 "                Size: %u\n"
   10898                 "             Version: %u\n"
   10899                 "           PortIndex: %u\n"
   10900                 " Is Interlace Format: %d\n"
   10901                 "   Interlace Formats: %u\n"
   10902                 "=========== End of Interlace ===========",
   10903                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
   10904                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
   10905     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   10906         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   10907 
   10908         DEBUG_PRINT_HIGH(
   10909                 "-------- Frame Format --------\n"
   10910                 "             Picture Type: %d\n"
   10911                 "           Interlace Type: %d\n"
   10912                 " Pan Scan Total Frame Num: %u\n"
   10913                 "   Concealed Macro Blocks: %u\n"
   10914                 "               frame rate: %u\n"
   10915                 "               Time Stamp: %llu\n"
   10916                 "           Aspect Ratio X: %u\n"
   10917                 "           Aspect Ratio Y: %u",
   10918                 fminfo->ePicType,
   10919                 fminfo->interlaceType,
   10920                 (unsigned int)fminfo->panScan.numWindows,
   10921                 (unsigned int)fminfo->nConcealedMacroblocks,
   10922                 (unsigned int)fminfo->nFrameRate,
   10923                 fminfo->nTimeStamp,
   10924                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
   10925                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
   10926 
   10927         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   10928             DEBUG_PRINT_HIGH(
   10929                     "------------------------------"
   10930                     "     Pan Scan Frame Num: %u\n"
   10931                     "            Rectangle x: %d\n"
   10932                     "            Rectangle y: %d\n"
   10933                     "           Rectangle dx: %d\n"
   10934                     "           Rectangle dy: %d",
   10935                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
   10936                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
   10937         }
   10938 
   10939         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   10940     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
   10941         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   10942         DEBUG_PRINT_HIGH(
   10943                 "------------------ Framepack Format ----------\n"
   10944                 "                           id: %u \n"
   10945                 "                  cancel_flag: %u \n"
   10946                 "                         type: %u \n"
   10947                 " quincunx_sampling_flagFormat: %u \n"
   10948                 "  content_interpretation_type: %u \n"
   10949                 "        spatial_flipping_flag: %u \n"
   10950                 "          frame0_flipped_flag: %u \n"
   10951                 "             field_views_flag: %u \n"
   10952                 " current_frame_is_frame0_flag: %u \n"
   10953                 "   frame0_self_contained_flag: %u \n"
   10954                 "   frame1_self_contained_flag: %u \n"
   10955                 "       frame0_grid_position_x: %u \n"
   10956                 "       frame0_grid_position_y: %u \n"
   10957                 "       frame1_grid_position_x: %u \n"
   10958                 "       frame1_grid_position_y: %u \n"
   10959                 "                reserved_byte: %u \n"
   10960                 "            repetition_period: %u \n"
   10961                 "               extension_flag: %u \n"
   10962                 "================== End of Framepack ===========",
   10963                 (unsigned int)framepack->id,
   10964                 (unsigned int)framepack->cancel_flag,
   10965                 (unsigned int)framepack->type,
   10966                 (unsigned int)framepack->quincunx_sampling_flag,
   10967                 (unsigned int)framepack->content_interpretation_type,
   10968                 (unsigned int)framepack->spatial_flipping_flag,
   10969                 (unsigned int)framepack->frame0_flipped_flag,
   10970                 (unsigned int)framepack->field_views_flag,
   10971                 (unsigned int)framepack->current_frame_is_frame0_flag,
   10972                 (unsigned int)framepack->frame0_self_contained_flag,
   10973                 (unsigned int)framepack->frame1_self_contained_flag,
   10974                 (unsigned int)framepack->frame0_grid_position_x,
   10975                 (unsigned int)framepack->frame0_grid_position_y,
   10976                 (unsigned int)framepack->frame1_grid_position_x,
   10977                 (unsigned int)framepack->frame1_grid_position_y,
   10978                 (unsigned int)framepack->reserved_byte,
   10979                 (unsigned int)framepack->repetition_period,
   10980                 (unsigned int)framepack->extension_flag);
   10981     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
   10982         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   10983         DEBUG_PRINT_HIGH(
   10984                 "---- QP (Frame quantization parameter) ----\n"
   10985                 "    Frame QP: %u \n"
   10986                 "================ End of QP ================\n",
   10987                 (unsigned int)qp->nQP);
   10988     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
   10989         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
   10990         DEBUG_PRINT_HIGH(
   10991                 "--------- Input bits information --------\n"
   10992                 "    Header bits: %u \n"
   10993                 "     Frame bits: %u \n"
   10994                 "===== End of Input bits information =====\n",
   10995                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
   10996     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
   10997         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
   10998         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
   10999         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
   11000         OMX_U32 i = 0;
   11001         DEBUG_PRINT_HIGH(
   11002                 "--------------  Userdata  -------------\n"
   11003                 "    Stream userdata type: %u\n"
   11004                 "          userdata size: %u\n"
   11005                 "    STREAM_USERDATA:",
   11006                 (unsigned int)userdata->type, (unsigned int)userdata_size);
   11007                 for (i = 0; i < userdata_size; i+=4) {
   11008                     DEBUG_PRINT_HIGH("        %x %x %x %x",
   11009                         data_ptr[i], data_ptr[i+1],
   11010                         data_ptr[i+2], data_ptr[i+3]);
   11011                 }
   11012         DEBUG_PRINT_HIGH(
   11013                 "=========== End of Userdata ===========");
   11014     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI) {
   11015         OMX_QCOM_EXTRADATA_VQZIPSEI *vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   11016         DEBUG_PRINT_HIGH(
   11017                 "--------------  VQZip  -------------\n"
   11018                 "    Size: %u\n",
   11019                 (unsigned int)vq->nSize);
   11020         DEBUG_PRINT_HIGH( "=========== End of VQZip ===========");
   11021     } else if (extra->eType == OMX_ExtraDataNone) {
   11022         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   11023     } else {
   11024         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   11025     }
   11026 }
   11027 
   11028 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11029         OMX_U32 interlaced_format_type, bool is_mbaff)
   11030 {
   11031     OMX_STREAMINTERLACEFORMAT *interlace_format;
   11032 
   11033     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   11034         return;
   11035     }
   11036     if (!extra) {
   11037        DEBUG_PRINT_ERROR("Error: append_interlace_extradata - invalid input");
   11038        return;
   11039     }
   11040     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   11041     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11042     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11043     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   11044     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   11045     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   11046     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   11047     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   11048     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11049 
   11050     if ((interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
   11051         interlace_format->bInterlaceFormat = OMX_FALSE;
   11052         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   11053         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11054     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
   11055         interlace_format->bInterlaceFormat = OMX_TRUE;
   11056         interlace_format->nInterlaceFormats =  OMX_InterlaceInterleaveFrameTopFieldFirst;
   11057         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11058     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
   11059         interlace_format->bInterlaceFormat = OMX_TRUE;
   11060         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   11061         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   11062     } else {
   11063         interlace_format->bInterlaceFormat = OMX_TRUE;
   11064         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   11065         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   11066     }
   11067     print_debug_extradata(extra);
   11068 }
   11069 
   11070 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11071 {
   11072     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
   11073     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
   11074         return;
   11075     }
   11076     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
   11077     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11078     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11079     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
   11080     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
   11081     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
   11082     frame_dimension->nDecWidth = rectangle.nLeft;
   11083     frame_dimension->nDecHeight = rectangle.nTop;
   11084     frame_dimension->nActualWidth = rectangle.nWidth;
   11085     frame_dimension->nActualHeight = rectangle.nHeight;
   11086 }
   11087 
   11088 void omx_vdec::fill_aspect_ratio_info(
   11089         struct vdec_aspectratioinfo *aspect_ratio_info,
   11090         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   11091 {
   11092     m_extradata = frame_info;
   11093     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   11094     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   11095     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
   11096             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
   11097 }
   11098 
   11099 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11100         OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
   11101         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
   11102         struct vdec_aspectratioinfo *aspect_ratio_info)
   11103 {
   11104     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   11105     struct msm_vidc_panscan_window *panscan_window;
   11106     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   11107         return;
   11108     }
   11109     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   11110     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11111     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11112     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   11113     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   11114     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   11115     switch (picture_type) {
   11116         case PICTURE_TYPE_I:
   11117             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   11118             break;
   11119         case PICTURE_TYPE_P:
   11120             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   11121             break;
   11122         case PICTURE_TYPE_B:
   11123             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   11124             break;
   11125         default:
   11126             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   11127     }
   11128     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   11129         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   11130     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   11131         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   11132     else
   11133         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   11134     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   11135     frame_info->nConcealedMacroblocks = num_conceal_mb;
   11136     frame_info->nFrameRate = frame_rate;
   11137     frame_info->nTimeStamp = time_stamp;
   11138     frame_info->panScan.numWindows = 0;
   11139     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   11140         if (m_disp_hor_size && m_disp_vert_size) {
   11141             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   11142             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   11143         } else {
   11144             frame_info->displayAspectRatio.displayHorizontalSize = 0;
   11145             frame_info->displayAspectRatio.displayVerticalSize = 0;
   11146         }
   11147     }
   11148 
   11149     if (panscan_payload) {
   11150         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   11151         panscan_window = &panscan_payload->wnd[0];
   11152         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   11153             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   11154             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   11155             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   11156             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   11157             panscan_window++;
   11158         }
   11159     }
   11160     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   11161     print_debug_extradata(extra);
   11162 }
   11163 
   11164 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11165 {
   11166     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   11167     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   11168     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11169     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11170     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   11171     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   11172     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
   11173     *portDefn = m_port_def;
   11174     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
   11175             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
   11176             (unsigned int)portDefn->format.video.nFrameWidth,
   11177             (unsigned int)portDefn->format.video.nStride,
   11178             (unsigned int)portDefn->format.video.nSliceHeight);
   11179 }
   11180 
   11181 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11182         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
   11183 {
   11184     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
   11185     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
   11186         DEBUG_PRINT_ERROR("frame packing size mismatch");
   11187         return;
   11188     }
   11189     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
   11190     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11191     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11192     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
   11193     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   11194     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   11195     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   11196     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
   11197     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11198     memcpy(&framepack->id, s3d_frame_packing_payload,
   11199         sizeof(struct msm_vidc_s3d_frame_packing_payload));
   11200     memcpy(&m_frame_pack_arrangement, framepack,
   11201         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   11202     print_debug_extradata(extra);
   11203 }
   11204 
   11205 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11206             struct msm_vidc_frame_qp_payload *qp_payload)
   11207 {
   11208     OMX_QCOM_EXTRADATA_QP * qp = NULL;
   11209     if (!qp_payload) {
   11210         DEBUG_PRINT_ERROR("QP payload is NULL");
   11211         return;
   11212     }
   11213     extra->nSize = OMX_QP_EXTRADATA_SIZE;
   11214     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11215     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11216     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
   11217     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
   11218     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   11219     qp->nQP = qp_payload->frame_qp;
   11220     print_debug_extradata(extra);
   11221 }
   11222 
   11223 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11224             struct msm_vidc_frame_bits_info_payload *bits_payload)
   11225 {
   11226     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
   11227     if (!bits_payload) {
   11228         DEBUG_PRINT_ERROR("bits info payload is NULL");
   11229         return;
   11230     }
   11231     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
   11232     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11233     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11234     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
   11235     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
   11236     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
   11237     bits->frame_bits = bits_payload->frame_bits;
   11238     bits->header_bits = bits_payload->header_bits;
   11239     print_debug_extradata(extra);
   11240 }
   11241 
   11242 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11243             OMX_OTHER_EXTRADATATYPE *p_user)
   11244 {
   11245     int userdata_size = 0;
   11246     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
   11247     userdata_payload =
   11248         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
   11249     userdata_size = p_user->nDataSize;
   11250     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
   11251     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11252     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11253     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
   11254     extra->nDataSize = userdata_size;
   11255     if (extra->nDataSize && (p_user->nDataSize >= extra->nDataSize))
   11256         memcpy(extra->data, p_user->data, extra->nDataSize);
   11257     print_debug_extradata(extra);
   11258 }
   11259 
   11260 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   11261 {
   11262     if (!client_extradata) {
   11263         return;
   11264     }
   11265     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   11266     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11267     extra->eType = OMX_ExtraDataNone;
   11268     extra->nDataSize = 0;
   11269     extra->data[0] = 0;
   11270 
   11271     print_debug_extradata(extra);
   11272 }
   11273 
   11274 void omx_vdec::append_vqzip_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   11275         struct msm_vidc_vqzip_sei_payload *vqzip_payload)
   11276 {
   11277     OMX_QCOM_EXTRADATA_VQZIPSEI *vq = NULL;
   11278 
   11279     extra->nSize = OMX_VQZIPSEI_EXTRADATA_SIZE + vqzip_payload->size;
   11280     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   11281     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11282     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataVQZipSEI;
   11283     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_VQZIPSEI) + vqzip_payload->size;
   11284 
   11285     vq = (OMX_QCOM_EXTRADATA_VQZIPSEI *)(void *)extra->data;
   11286     vq->nSize = vqzip_payload->size;
   11287     memcpy(vq->data, vqzip_payload->data, vqzip_payload->size);
   11288 
   11289     print_debug_extradata(extra);
   11290 }
   11291 
   11292 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   11293 {
   11294     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   11295     if (index >= drv_ctx.ip_buf.actualcount) {
   11296         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
   11297         return OMX_ErrorInsufficientResources;
   11298     }
   11299     if (m_desc_buffer_ptr == NULL) {
   11300         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   11301                     calloc( (sizeof(desc_buffer_hdr)),
   11302                             drv_ctx.ip_buf.actualcount);
   11303         if (m_desc_buffer_ptr == NULL) {
   11304             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
   11305             return OMX_ErrorInsufficientResources;
   11306         }
   11307     }
   11308 
   11309     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   11310     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   11311         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
   11312         return OMX_ErrorInsufficientResources;
   11313     }
   11314 
   11315     return eRet;
   11316 }
   11317 
   11318 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   11319 {
   11320     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
   11321     if (m_demux_entries < 8192) {
   11322         m_demux_offsets[m_demux_entries++] = address_offset;
   11323     }
   11324     return;
   11325 }
   11326 
   11327 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   11328 {
   11329     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   11330     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   11331     OMX_U32 index = 0;
   11332 
   11333     m_demux_entries = 0;
   11334 
   11335     while (index < bytes_to_parse) {
   11336         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   11337                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   11338                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   11339                  (buf[index+2] == 0x01)) ) {
   11340             //Found start code, insert address offset
   11341             insert_demux_addr_offset(index);
   11342             if (buf[index+2] == 0x01) // 3 byte start code
   11343                 index += 3;
   11344             else                      //4 byte start code
   11345                 index += 4;
   11346         } else
   11347             index++;
   11348     }
   11349     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
   11350     return;
   11351 }
   11352 
   11353 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   11354 {
   11355     //fix this, handle 3 byte start code, vc1 terminator entry
   11356     OMX_U8 *p_demux_data = NULL;
   11357     OMX_U32 desc_data = 0;
   11358     OMX_U32 start_addr = 0;
   11359     OMX_U32 nal_size = 0;
   11360     OMX_U32 suffix_byte = 0;
   11361     OMX_U32 demux_index = 0;
   11362     OMX_U32 buffer_index = 0;
   11363 
   11364     if (m_desc_buffer_ptr == NULL) {
   11365         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   11366         return OMX_ErrorBadParameter;
   11367     }
   11368 
   11369     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   11370     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   11371         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
   11372         return OMX_ErrorBadParameter;
   11373     }
   11374 
   11375     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   11376 
   11377     if ( ((OMX_U8*)p_demux_data == NULL) ||
   11378             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   11379         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   11380         return OMX_ErrorBadParameter;
   11381     } else {
   11382         for (; demux_index < m_demux_entries; demux_index++) {
   11383             desc_data = 0;
   11384             start_addr = m_demux_offsets[demux_index];
   11385             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   11386                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   11387             } else {
   11388                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   11389             }
   11390             if (demux_index < (m_demux_entries - 1)) {
   11391                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   11392             } else {
   11393                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   11394             }
   11395             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
   11396                     (unsigned int)start_addr,
   11397                     (unsigned int)suffix_byte,
   11398                     (unsigned int)nal_size,
   11399                     (unsigned int)demux_index);
   11400             desc_data = (start_addr >> 3) << 1;
   11401             desc_data |= (start_addr & 7) << 21;
   11402             desc_data |= suffix_byte << 24;
   11403 
   11404             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   11405             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   11406             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   11407             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   11408 
   11409             p_demux_data += 16;
   11410         }
   11411         if (codec_type_parse == CODEC_TYPE_VC1) {
   11412             DEBUG_PRINT_LOW("VC1 terminator entry");
   11413             desc_data = 0;
   11414             desc_data = 0x82 << 24;
   11415             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   11416             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   11417             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   11418             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   11419             p_demux_data += 16;
   11420             m_demux_entries++;
   11421         }
   11422         //Add zero word to indicate end of descriptors
   11423         memset(p_demux_data, 0, sizeof(OMX_U32));
   11424 
   11425         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   11426         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
   11427     }
   11428     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   11429     m_demux_entries = 0;
   11430     DEBUG_PRINT_LOW("Demux table complete!");
   11431     return OMX_ErrorNone;
   11432 }
   11433 
   11434 void omx_vdec::request_perf_level(enum vidc_perf_level perf_level)
   11435 {
   11436     struct v4l2_control control;
   11437     char property_value[PROPERTY_VALUE_MAX] = {0};
   11438 
   11439     property_get("vidc.debug.turbo", property_value, "0");
   11440     memset(&control, 0, sizeof(v4l2_control));
   11441     control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   11442     switch (perf_level) {
   11443     case VIDC_NOMINAL:
   11444         if (atoi(property_value))
   11445             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   11446         else
   11447             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   11448         break;
   11449     case VIDC_TURBO:
   11450         control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   11451         break;
   11452      default:
   11453         DEBUG_PRINT_ERROR("Requested PERF level not supported");
   11454         break;
   11455     }
   11456     if ((current_perf_level == (OMX_U32)control.value) && !in_reconfig)
   11457         return;
   11458 
   11459     DEBUG_PRINT_HIGH("changing performance level to %d", control.value);
   11460     if (!ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   11461         current_perf_level = control.value;
   11462     } else {
   11463         DEBUG_PRINT_ERROR("Failed to set PERF level");
   11464     }
   11465 }
   11466 
   11467 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   11468 {
   11469     enabled = false;
   11470     omx = NULL;
   11471     init_members();
   11472     ColorFormat = OMX_COLOR_FormatMax;
   11473     dest_format = YCbCr420P;
   11474 }
   11475 
   11476 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   11477 {
   11478     omx = reinterpret_cast<omx_vdec*>(client);
   11479 }
   11480 
   11481 void omx_vdec::allocate_color_convert_buf::init_members()
   11482 {
   11483     allocated_count = 0;
   11484     buffer_size_req = 0;
   11485     buffer_alignment_req = 0;
   11486     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   11487     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   11488     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   11489     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   11490 #ifdef USE_ION
   11491     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   11492 #endif
   11493     for (int i = 0; i < MAX_COUNT; i++)
   11494         pmem_fd[i] = -1;
   11495 }
   11496 
   11497 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   11498 {
   11499     c2d.destroy();
   11500 }
   11501 
   11502 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   11503 {
   11504     bool status = true;
   11505     unsigned int src_size = 0, destination_size = 0;
   11506     OMX_COLOR_FORMATTYPE drv_color_format;
   11507     if (!omx) {
   11508         DEBUG_PRINT_ERROR("Invalid client in color convert");
   11509         return false;
   11510     }
   11511     if (!enabled) {
   11512         DEBUG_PRINT_HIGH("No color conversion required");
   11513         return status;
   11514     }
   11515     pthread_mutex_lock(&omx->c_lock);
   11516     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   11517             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   11518         DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
   11519         status = false;
   11520         goto fail_update_buf_req;
   11521     }
   11522     c2d.close();
   11523     status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
   11524             omx->drv_ctx.video_resolution.frame_width,
   11525             NV12_128m,dest_format);
   11526     if (status) {
   11527         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   11528         if (status)
   11529             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   11530     }
   11531     if (status) {
   11532         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   11533                 !destination_size) {
   11534             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
   11535                     "driver size %u destination size %d",
   11536                     src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
   11537                     destination_size);
   11538             status = false;
   11539             c2d.close();
   11540             buffer_size_req = 0;
   11541         } else {
   11542             buffer_size_req = destination_size;
   11543             if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
   11544                 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
   11545             if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   11546                 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   11547         }
   11548     }
   11549 fail_update_buf_req:
   11550     pthread_mutex_unlock(&omx->c_lock);
   11551     return status;
   11552 }
   11553 
   11554 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   11555         OMX_COLOR_FORMATTYPE dest_color_format)
   11556 {
   11557     bool status = true;
   11558     OMX_COLOR_FORMATTYPE drv_color_format;
   11559     if (!omx) {
   11560         DEBUG_PRINT_ERROR("Invalid client in color convert");
   11561         return false;
   11562     }
   11563     pthread_mutex_lock(&omx->c_lock);
   11564     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   11565         if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   11566             drv_color_format = (OMX_COLOR_FORMATTYPE)
   11567                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   11568         else
   11569             drv_color_format = (OMX_COLOR_FORMATTYPE)
   11570                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11571      else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC) {
   11572          drv_color_format = (OMX_COLOR_FORMATTYPE)
   11573                   QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11574      } else {
   11575         DEBUG_PRINT_ERROR("Incorrect color format");
   11576         status = false;
   11577     }
   11578     if (status &&
   11579         drv_color_format != dest_color_format &&
   11580         drv_color_format != (OMX_COLOR_FORMATTYPE)
   11581                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView &&
   11582         drv_color_format != (OMX_COLOR_FORMATTYPE)
   11583                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed &&
   11584         dest_color_format != (OMX_COLOR_FORMATTYPE)
   11585                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed) {
   11586         DEBUG_PRINT_LOW("Enabling C2D");
   11587         if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
   11588            (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
   11589             DEBUG_PRINT_ERROR("Unsupported color format for c2d");
   11590             status = false;
   11591         } else {
   11592             ColorFormat = dest_color_format;
   11593             dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
   11594                     YCbCr420P : YCbCr420SP;
   11595             if (enabled)
   11596                 c2d.destroy();
   11597             enabled = false;
   11598             if (!c2d.init()) {
   11599                 DEBUG_PRINT_ERROR("open failed for c2d");
   11600                 status = false;
   11601             } else
   11602                 enabled = true;
   11603         }
   11604     } else {
   11605         if (enabled)
   11606             c2d.destroy();
   11607         enabled = false;
   11608     }
   11609     pthread_mutex_unlock(&omx->c_lock);
   11610     return status;
   11611 }
   11612 
   11613 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   11614 {
   11615     if (!omx) {
   11616         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11617         return NULL;
   11618     }
   11619     if (!enabled)
   11620         return omx->m_out_mem_ptr;
   11621     return m_out_mem_ptr_client;
   11622 }
   11623 
   11624     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   11625 (OMX_BUFFERHEADERTYPE *bufadd)
   11626 {
   11627     if (!omx) {
   11628         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11629         return NULL;
   11630     }
   11631     if (!enabled)
   11632         return bufadd;
   11633 
   11634     unsigned index = 0;
   11635     index = bufadd - omx->m_out_mem_ptr;
   11636     if (index < omx->drv_ctx.op_buf.actualcount) {
   11637         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   11638         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   11639         bool status;
   11640         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   11641             pthread_mutex_lock(&omx->c_lock);
   11642             cache_clean_buffer(index);
   11643             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   11644                     omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
   11645                     pmem_baseaddress[index], pmem_baseaddress[index]);
   11646             if (!status) {
   11647                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
   11648                 m_out_mem_ptr_client[index].nFilledLen = 0;
   11649                 pthread_mutex_unlock(&omx->c_lock);
   11650                 return &m_out_mem_ptr_client[index];
   11651             } else {
   11652                 unsigned int filledLen = 0;
   11653                 c2d.get_output_filled_length(filledLen);
   11654                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
   11655                 cache_clean_invalidate_buffer(index);
   11656             }
   11657             pthread_mutex_unlock(&omx->c_lock);
   11658         } else
   11659             m_out_mem_ptr_client[index].nFilledLen = 0;
   11660         return &m_out_mem_ptr_client[index];
   11661     }
   11662     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
   11663     return NULL;
   11664 }
   11665 
   11666     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   11667 (OMX_BUFFERHEADERTYPE *bufadd)
   11668 {
   11669     if (!omx) {
   11670         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   11671         return NULL;
   11672     }
   11673     if (!enabled)
   11674         return bufadd;
   11675     unsigned index = 0;
   11676     index = bufadd - m_out_mem_ptr_client;
   11677     if (index < omx->drv_ctx.op_buf.actualcount) {
   11678         return &omx->m_out_mem_ptr[index];
   11679     }
   11680     DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
   11681     return NULL;
   11682 }
   11683     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   11684 (unsigned int &buffer_size)
   11685 {
   11686     bool status = true;
   11687     pthread_mutex_lock(&omx->c_lock);
   11688     if (!enabled)
   11689         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   11690     else {
   11691         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   11692             DEBUG_PRINT_ERROR("Get buffer size failed");
   11693             status = false;
   11694             goto fail_get_buffer_size;
   11695         }
   11696     }
   11697     if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
   11698         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   11699     if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   11700         buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   11701 fail_get_buffer_size:
   11702     pthread_mutex_unlock(&omx->c_lock);
   11703     return status;
   11704 }
   11705 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   11706         OMX_BUFFERHEADERTYPE *bufhdr)
   11707 {
   11708     unsigned int index = 0;
   11709 
   11710     if (!enabled)
   11711         return omx->free_output_buffer(bufhdr);
   11712     if (enabled && omx->is_component_secure())
   11713         return OMX_ErrorNone;
   11714     if (!allocated_count || !bufhdr) {
   11715         DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
   11716         return OMX_ErrorBadParameter;
   11717     }
   11718     index = bufhdr - m_out_mem_ptr_client;
   11719     if (index >= omx->drv_ctx.op_buf.actualcount) {
   11720         DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
   11721         return OMX_ErrorBadParameter;
   11722     }
   11723     if (pmem_fd[index] >= 0) {
   11724         munmap(pmem_baseaddress[index], buffer_size_req);
   11725         close(pmem_fd[index]);
   11726     }
   11727     pmem_fd[index] = -1;
   11728 #ifdef USE_ION
   11729     omx->free_ion_memory(&op_buf_ion_info[index]);
   11730 #endif
   11731     m_heap_ptr[index].video_heap_ptr = NULL;
   11732     if (allocated_count > 0)
   11733         allocated_count--;
   11734     else
   11735         allocated_count = 0;
   11736     if (!allocated_count) {
   11737         pthread_mutex_lock(&omx->c_lock);
   11738         c2d.close();
   11739         init_members();
   11740         pthread_mutex_unlock(&omx->c_lock);
   11741     }
   11742     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   11743 }
   11744 
   11745 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   11746         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   11747 {
   11748     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   11749     if (!enabled) {
   11750         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   11751         return eRet;
   11752     }
   11753     if (enabled && omx->is_component_secure()) {
   11754         DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
   11755                 omx->is_component_secure());
   11756         return OMX_ErrorUnsupportedSetting;
   11757     }
   11758     if (!bufferHdr || bytes > buffer_size_req) {
   11759         DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   11760         DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
   11761                 (unsigned int)buffer_size_req, (unsigned int)bytes);
   11762         return OMX_ErrorBadParameter;
   11763     }
   11764     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   11765         DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
   11766         return OMX_ErrorInsufficientResources;
   11767     }
   11768     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   11769     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   11770             port,appData,omx->drv_ctx.op_buf.buffer_size);
   11771     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   11772         DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
   11773         return eRet;
   11774     }
   11775     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   11776             (int)omx->drv_ctx.op_buf.actualcount) {
   11777         DEBUG_PRINT_ERROR("Invalid header index %ld",
   11778                (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
   11779         return OMX_ErrorUndefined;
   11780     }
   11781     unsigned int i = allocated_count;
   11782 #ifdef USE_ION
   11783     // Allocate color-conversion buffers as cached to improve software-reading
   11784     // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
   11785     // cache invalidation.
   11786     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   11787             buffer_size_req,buffer_alignment_req,
   11788             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   11789             ION_FLAG_CACHED);
   11790     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   11791     if (op_buf_ion_info[i].ion_device_fd < 0) {
   11792         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
   11793         return OMX_ErrorInsufficientResources;
   11794     }
   11795     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   11796             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   11797 
   11798     if (pmem_baseaddress[i] == MAP_FAILED) {
   11799         DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
   11800         close(pmem_fd[i]);
   11801         omx->free_ion_memory(&op_buf_ion_info[i]);
   11802         return OMX_ErrorInsufficientResources;
   11803     }
   11804     m_heap_ptr[i].video_heap_ptr = new VideoHeap (
   11805             op_buf_ion_info[i].ion_device_fd,buffer_size_req,
   11806             pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
   11807 #endif
   11808     m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get();
   11809     m_pmem_info_client[i].offset = 0;
   11810     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   11811     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   11812     m_platform_list_client[i].nEntries = 1;
   11813     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   11814     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   11815     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   11816     m_out_mem_ptr_client[i].nFilledLen = 0;
   11817     m_out_mem_ptr_client[i].nFlags = 0;
   11818     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   11819     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   11820     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   11821     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   11822     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   11823     m_out_mem_ptr_client[i].pAppPrivate = appData;
   11824     *bufferHdr = &m_out_mem_ptr_client[i];
   11825     DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr);
   11826     allocated_count++;
   11827     return eRet;
   11828 }
   11829 
   11830 bool omx_vdec::is_component_secure()
   11831 {
   11832     return secure_mode;
   11833 }
   11834 
   11835 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   11836 {
   11837     bool status = true;
   11838     if (!enabled) {
   11839         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   11840             if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   11841                     dest_color_format = (OMX_COLOR_FORMATTYPE)
   11842                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   11843                 else
   11844                     dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   11845         } else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12_UBWC){
   11846              dest_color_format = (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed;
   11847         } else
   11848             status = false;
   11849     } else {
   11850         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
   11851             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   11852             dest_color_format = ColorFormat;
   11853         } else
   11854             status = false;
   11855     }
   11856     return status;
   11857 }
   11858 
   11859 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
   11860         unsigned int index, unsigned int cmd)
   11861 {
   11862     if (!enabled) {
   11863         return OMX_ErrorNone;
   11864     }
   11865 
   11866     if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
   11867         DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
   11868         return OMX_ErrorBadParameter;
   11869     }
   11870 
   11871     struct ion_flush_data flush_data;
   11872     struct ion_custom_data custom_data;
   11873 
   11874     memset(&flush_data, 0x0, sizeof(flush_data));
   11875     memset(&custom_data, 0x0, sizeof(custom_data));
   11876 
   11877     flush_data.vaddr = pmem_baseaddress[index];
   11878     flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
   11879     flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
   11880     flush_data.length = buffer_size_req;
   11881     custom_data.cmd = cmd;
   11882     custom_data.arg = (unsigned long)&flush_data;
   11883 
   11884     DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
   11885             (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   11886             flush_data.fd, flush_data.handle, flush_data.vaddr,
   11887             flush_data.length);
   11888     int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
   11889     if (ret < 0) {
   11890         DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
   11891                 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   11892                 strerror(errno));
   11893         return OMX_ErrorUndefined;
   11894     }
   11895     return OMX_ErrorNone;
   11896 }
   11897 
   11898 void omx_vdec::buf_ref_add(int nPortIndex)
   11899 {
   11900     unsigned long i = 0;
   11901     bool buf_present = false;
   11902     long fd = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   11903     OMX_U32 offset = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   11904 
   11905     if (!dynamic_buf_mode || !out_dynamic_list) {
   11906         return;
   11907     }
   11908 
   11909     pthread_mutex_lock(&m_lock);
   11910     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11911         //check the buffer fd, offset, uv addr with list contents
   11912         //If present increment reference.
   11913         if ((out_dynamic_list[i].fd == fd) &&
   11914             (out_dynamic_list[i].offset == offset)) {
   11915                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
   11916                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11917                if (!secure_mode) {
   11918                    drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = out_dynamic_list[i].buffaddr;
   11919                }
   11920                buf_present = true;
   11921                break;
   11922         }
   11923     }
   11924     if (!buf_present) {
   11925         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11926             //search for a entry to insert details of the new buffer
   11927             if (out_dynamic_list[i].dup_fd < 0) {
   11928                 out_dynamic_list[i].fd = fd;
   11929                 out_dynamic_list[i].offset = offset;
   11930                 out_dynamic_list[i].dup_fd = dup(fd);
   11931                 out_dynamic_list[i].ref_count++;
   11932                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
   11933                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11934 
   11935                 if (!secure_mode) {
   11936                     drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   11937                             (OMX_U8*)mmap(0, drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len,
   11938                                           PROT_READ|PROT_WRITE, MAP_SHARED,
   11939                                           drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   11940                     //mmap returns (void *)-1 on failure and sets error code in errno.
   11941                     if (drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr == MAP_FAILED) {
   11942                         DEBUG_PRINT_ERROR("buf_ref_add: mmap failed - errno: %d", errno);
   11943                         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = NULL;
   11944                         break;
   11945                     }
   11946                     out_dynamic_list[i].buffaddr = drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr;
   11947                     out_dynamic_list[i].mapped_size = drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len;
   11948                     DEBUG_PRINT_LOW("mmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   11949                 }
   11950                 break;
   11951             }
   11952         }
   11953     }
   11954    pthread_mutex_unlock(&m_lock);
   11955 }
   11956 
   11957 void omx_vdec::buf_ref_remove()
   11958 {
   11959     unsigned long i = 0;
   11960 
   11961     if (!dynamic_buf_mode || !out_dynamic_list) {
   11962         return;
   11963     }
   11964 
   11965     pthread_mutex_lock(&m_lock);
   11966     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   11967         if (!secure_mode && out_dynamic_list[i].buffaddr && out_dynamic_list[i].mapped_size) {
   11968             DEBUG_PRINT_LOW("munmap: %p %ld", out_dynamic_list[i].buffaddr, out_dynamic_list[i].mapped_size);
   11969             munmap(out_dynamic_list[i].buffaddr,
   11970                         out_dynamic_list[i].mapped_size);
   11971         }
   11972 
   11973          DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
   11974                  (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   11975          close(out_dynamic_list[i].dup_fd);
   11976          out_dynamic_list[i].dup_fd = -1;
   11977     }
   11978     pthread_mutex_unlock(&m_lock);
   11979 
   11980     if (out_dynamic_list) {
   11981         free(out_dynamic_list);
   11982         out_dynamic_list = NULL;
   11983     }
   11984 }
   11985 
   11986 #ifdef _MSM8974_
   11987 void omx_vdec::send_codec_config() {
   11988     if (codec_config_flag) {
   11989         unsigned long p1 = 0; // Parameter - 1
   11990         unsigned long p2 = 0; // Parameter - 2
   11991         unsigned long ident = 0;
   11992         pthread_mutex_lock(&m_lock);
   11993         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   11994         while (m_etb_q.m_size) {
   11995             m_etb_q.pop_entry(&p1,&p2,&ident);
   11996             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   11997                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   11998                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   11999                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   12000                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   12001                         omx_report_error();
   12002                     }
   12003                 } else {
   12004                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   12005                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   12006                 }
   12007             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   12008                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   12009                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   12010                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   12011                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   12012                         omx_report_error ();
   12013                     }
   12014                 } else {
   12015                     pending_input_buffers++;
   12016                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   12017                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   12018                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   12019                 }
   12020             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   12021                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   12022                         (OMX_BUFFERHEADERTYPE *)p1);
   12023                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   12024             }
   12025         }
   12026         pthread_mutex_unlock(&m_lock);
   12027     }
   12028 }
   12029 #endif
   12030 
   12031 omx_vdec::perf_control::perf_control()
   12032 {
   12033     m_perf_lib = NULL;
   12034     m_perf_handle = 0;
   12035     m_perf_lock_acquire = NULL;
   12036     m_perf_lock_release = NULL;
   12037 }
   12038 
   12039 omx_vdec::perf_control::~perf_control()
   12040 {
   12041     if (m_perf_handle != 0 && m_perf_lock_release) {
   12042         DEBUG_PRINT_LOW("NOTE2: release perf lock");
   12043         m_perf_lock_release(m_perf_handle);
   12044     }
   12045     if (m_perf_lib) {
   12046         dlclose(m_perf_lib);
   12047     }
   12048 }
   12049 
   12050 struct omx_vdec::perf_control::mpctl_stats omx_vdec::perf_control::mpctl_obj = {0, 0, 0};
   12051 
   12052 omx_vdec::perf_lock omx_vdec::perf_control::m_perf_lock;
   12053 
   12054 void omx_vdec::perf_control::send_hint_to_mpctl(bool state)
   12055 {
   12056     if (load_lib() == false) {
   12057        return;
   12058     }
   12059     m_perf_lock.lock();
   12060     /* 0x4401 maps to video decode playback hint
   12061      * in perflock, enum number is 44 and state
   12062      * being sent on perflock acquire is 01 (true)
   12063      */
   12064     int arg = 0x4401;
   12065 
   12066     if (state == true) {
   12067         mpctl_obj.vid_inst_count++;
   12068     } else if (state == false) {
   12069         mpctl_obj.vid_inst_count--;
   12070     }
   12071 
   12072     if (m_perf_lock_acquire && mpctl_obj.vid_inst_count == 1 && mpctl_obj.vid_acquired == false) {
   12073         mpctl_obj.vid_disp_handle = m_perf_lock_acquire(0, 0, &arg, sizeof(arg) / sizeof(int));
   12074         mpctl_obj.vid_acquired = true;
   12075         DEBUG_PRINT_INFO("Video slvp perflock acquired");
   12076     } else if (m_perf_lock_release && (mpctl_obj.vid_inst_count == 0 || mpctl_obj.vid_inst_count > 1) && mpctl_obj.vid_acquired == true) {
   12077         m_perf_lock_release(mpctl_obj.vid_disp_handle);
   12078         mpctl_obj.vid_acquired = false;
   12079         DEBUG_PRINT_INFO("Video slvp perflock released");
   12080     }
   12081     m_perf_lock.unlock();
   12082 }
   12083 
   12084 void omx_vdec::perf_control::request_cores(int frame_duration_us)
   12085 {
   12086     if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
   12087         return;
   12088     }
   12089     bool retVal = load_lib();
   12090     if (retVal && m_perf_lock_acquire && m_perf_handle == 0) {
   12091         int arg = 0x700 /*base value*/ + 2 /*cores*/;
   12092         m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
   12093         if (m_perf_handle) {
   12094             DEBUG_PRINT_HIGH("perf lock acquired");
   12095         }
   12096     }
   12097 }
   12098 
   12099 bool omx_vdec::perf_control::load_lib()
   12100 {
   12101     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
   12102     if (m_perf_lib)
   12103         return true;
   12104 
   12105     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
   12106         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
   12107         goto handle_err;
   12108     }
   12109 
   12110     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
   12111         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
   12112         goto handle_err;
   12113     } else {
   12114         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
   12115         if (m_perf_lock_acquire == NULL) {
   12116             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
   12117             goto handle_err;
   12118         }
   12119         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
   12120         if (m_perf_lock_release == NULL) {
   12121             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
   12122             goto handle_err;
   12123         }
   12124     }
   12125     return true;
   12126 
   12127 handle_err:
   12128     if (m_perf_lib) {
   12129         dlclose(m_perf_lib);
   12130     }
   12131     m_perf_lib = NULL;
   12132     return false;
   12133 }
   12134 
   12135 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
   12136                             unsigned long nMaxFrameHeight)
   12137 {
   12138 
   12139     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   12140     int ret = 0;
   12141     unsigned long min_res_buf_count = 0;
   12142 
   12143     eRet = enable_smoothstreaming();
   12144     if (eRet != OMX_ErrorNone) {
   12145          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
   12146          return eRet;
   12147      }
   12148 
   12149      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
   12150              nMaxFrameWidth,
   12151              nMaxFrameHeight);
   12152      m_smoothstreaming_mode = true;
   12153      m_smoothstreaming_width = nMaxFrameWidth;
   12154      m_smoothstreaming_height = nMaxFrameHeight;
   12155 
   12156      //Get upper limit buffer count for min supported resolution
   12157      struct v4l2_format fmt;
   12158      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   12159      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
   12160      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
   12161      fmt.fmt.pix_mp.pixelformat = output_capability;
   12162 
   12163      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   12164      if (ret) {
   12165          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
   12166                            m_decoder_capability.min_height,
   12167                            m_decoder_capability.min_width);
   12168          return OMX_ErrorUnsupportedSetting;
   12169      }
   12170 
   12171      eRet = get_buffer_req(&drv_ctx.op_buf);
   12172      if (eRet != OMX_ErrorNone) {
   12173          DEBUG_PRINT_ERROR("failed to get_buffer_req");
   12174          return eRet;
   12175      }
   12176 
   12177      min_res_buf_count = drv_ctx.op_buf.mincount;
   12178      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
   12179                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
   12180 
   12181      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
   12182                        m_smoothstreaming_width, m_smoothstreaming_height);
   12183      eRet = is_video_session_supported();
   12184      if (eRet != OMX_ErrorNone) {
   12185          DEBUG_PRINT_ERROR("video session is not supported");
   12186          return eRet;
   12187      }
   12188 
   12189      //Get upper limit buffer size for max smooth streaming resolution set
   12190      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   12191      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   12192      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   12193      fmt.fmt.pix_mp.pixelformat = output_capability;
   12194      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   12195      if (ret) {
   12196          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
   12197          return OMX_ErrorUnsupportedSetting;
   12198      }
   12199 
   12200      eRet = get_buffer_req(&drv_ctx.op_buf);
   12201      if (eRet != OMX_ErrorNone) {
   12202          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
   12203          return eRet;
   12204      }
   12205      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
   12206                      (unsigned int)drv_ctx.op_buf.buffer_size);
   12207 
   12208      drv_ctx.op_buf.mincount = min_res_buf_count;
   12209      drv_ctx.op_buf.actualcount = min_res_buf_count;
   12210      drv_ctx.op_buf.buffer_size = drv_ctx.op_buf.buffer_size;
   12211      eRet = set_buffer_req(&drv_ctx.op_buf);
   12212      if (eRet != OMX_ErrorNone) {
   12213          DEBUG_PRINT_ERROR("failed to set_buffer_req");
   12214          return eRet;
   12215      }
   12216 
   12217      eRet = get_buffer_req(&drv_ctx.op_buf);
   12218      if (eRet != OMX_ErrorNone) {
   12219          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
   12220          return eRet;
   12221      }
   12222      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
   12223                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
   12224      return eRet;
   12225 }
   12226 
   12227 //static
   12228 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
   12229 
   12230 #ifndef FLEXYUV_SUPPORTED
   12231     return OMX_ErrorUndefined;
   12232 #else
   12233 
   12234     if (pParam == NULL) {
   12235         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
   12236         return OMX_ErrorBadParameter;
   12237     }
   12238 
   12239     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
   12240 
   12241     MediaImage *img = &(params->sMediaImage);
   12242     switch(params->eColorFormat) {
   12243         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   12244         {
   12245             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   12246             img->mNumPlanes = 3;
   12247             // mWidth and mHeight represent the W x H of the largest plane
   12248             // In our case, this happens to be the Stride x Scanlines of Y plane
   12249             img->mWidth = params->nFrameWidth;
   12250             img->mHeight = params->nFrameHeight;
   12251             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12252             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
   12253             img->mBitDepth = 8;
   12254             //Plane 0 (Y)
   12255             img->mPlane[MediaImage::Y].mOffset = 0;
   12256             img->mPlane[MediaImage::Y].mColInc = 1;
   12257             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
   12258             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
   12259             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
   12260             //Plane 1 (U)
   12261             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
   12262             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
   12263             img->mPlane[MediaImage::U].mRowInc =
   12264                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12265             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
   12266             img->mPlane[MediaImage::U].mVertSubsampling = 2;
   12267             //Plane 2 (V)
   12268             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
   12269             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
   12270             img->mPlane[MediaImage::V].mRowInc =
   12271                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   12272             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
   12273             img->mPlane[MediaImage::V].mVertSubsampling = 2;
   12274             break;
   12275         }
   12276 
   12277         case OMX_COLOR_FormatYUV420Planar:
   12278         case OMX_COLOR_FormatYUV420SemiPlanar:
   12279             // We need not describe the standard OMX linear formats as these are
   12280             // understood by client. Fail this deliberately to let client fill-in
   12281             return OMX_ErrorUnsupportedSetting;
   12282 
   12283         default:
   12284             // Rest all formats which are non-linear cannot be described
   12285             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
   12286             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   12287             return OMX_ErrorNone;
   12288     };
   12289 
   12290     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
   12291     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
   12292     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
   12293     for (size_t i = 0; i < img->mNumPlanes; ++i) {
   12294         DEBUG_PRINT_LOW("    Plane[%zd] : offset=%d / xStep=%d / yStep = %d",
   12295                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
   12296     }
   12297     return OMX_ErrorNone;
   12298 #endif //FLEXYUV_SUPPORTED
   12299 }
   12300 
   12301 void omx_vdec::prefetchNewBuffers() {
   12302 
   12303     struct v4l2_decoder_cmd dec;
   12304     uint32_t prefetch_count;
   12305     uint32_t prefetch_size;
   12306     uint32_t want_size;
   12307     uint32_t have_size;
   12308     int color_fmt, rc;
   12309     uint32_t new_calculated_size;
   12310     uint32_t new_buffer_size;
   12311     uint32_t new_buffer_count;
   12312     uint32_t old_buffer_size;
   12313     uint32_t old_buffer_count;
   12314 
   12315     memset((void *)&dec, 0 , sizeof(dec));
   12316     DEBUG_PRINT_LOW("Old size : %d, count : %d, width : %u, height : %u\n",
   12317             (int)drv_ctx.op_buf.buffer_size, drv_ctx.op_buf.actualcount,
   12318             drv_ctx.video_resolution.frame_width,
   12319             drv_ctx.video_resolution.frame_height);
   12320     dec.cmd = V4L2_DEC_QCOM_CMD_RECONFIG_HINT;
   12321     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   12322         DEBUG_PRINT_ERROR("Buffer info cmd failed : %d\n", errno);
   12323     } else {
   12324         DEBUG_PRINT_LOW("From driver, new size is %d, count is %d\n",
   12325                 dec.raw.data[0], dec.raw.data[1]);
   12326     }
   12327 
   12328     switch ((int)drv_ctx.output_format) {
   12329     case VDEC_YUV_FORMAT_NV12:
   12330         color_fmt = COLOR_FMT_NV12;
   12331         break;
   12332     case VDEC_YUV_FORMAT_NV12_UBWC:
   12333         color_fmt = COLOR_FMT_NV12_UBWC;
   12334         break;
   12335     default:
   12336         color_fmt = -1;
   12337     }
   12338 
   12339     new_calculated_size = VENUS_BUFFER_SIZE(color_fmt, m_reconfig_width, m_reconfig_height);
   12340     DEBUG_PRINT_LOW("New calculated size for width : %d, height : %d, is %d\n",
   12341             m_reconfig_width, m_reconfig_height, new_calculated_size);
   12342     new_buffer_size = (dec.raw.data[0] > new_calculated_size) ? dec.raw.data[0] : new_calculated_size;
   12343     new_buffer_count = dec.raw.data[1];
   12344     old_buffer_size = drv_ctx.op_buf.buffer_size;
   12345     old_buffer_count = drv_ctx.op_buf.actualcount;
   12346 
   12347     new_buffer_count = old_buffer_count > new_buffer_count ? old_buffer_count : new_buffer_count;
   12348 
   12349     prefetch_count = new_buffer_count;
   12350     prefetch_size = new_buffer_size - old_buffer_size;
   12351     want_size = new_buffer_size * new_buffer_count;
   12352     have_size = old_buffer_size * old_buffer_count;
   12353 
   12354     if (want_size > have_size) {
   12355         DEBUG_PRINT_LOW("Want: %d, have : %d\n", want_size, have_size);
   12356         DEBUG_PRINT_LOW("prefetch_count: %d, prefetch_size : %d\n", prefetch_count, prefetch_size);
   12357 
   12358         int ion_fd = open(MEM_DEVICE, O_RDONLY);
   12359         if (ion_fd < 0) {
   12360             DEBUG_PRINT_ERROR("Ion fd open failed : %d\n", ion_fd);
   12361             return;
   12362         }
   12363 
   12364         struct ion_custom_data *custom_data = (struct ion_custom_data*) malloc(sizeof(*custom_data));
   12365         struct ion_prefetch_data *prefetch_data = (struct ion_prefetch_data*) malloc(sizeof(*prefetch_data));
   12366         struct ion_prefetch_regions *regions = (struct ion_prefetch_regions*) malloc(sizeof(*regions));
   12367         size_t *sizes = (size_t*) malloc(sizeof(size_t) * prefetch_count);
   12368 
   12369         if (custom_data == NULL || prefetch_data == NULL || regions == NULL || sizes == NULL) {
   12370             DEBUG_PRINT_ERROR("prefetch data allocation failed");
   12371             goto prefetch_exit;
   12372         }
   12373 
   12374         for (uint32_t i = 0; i < prefetch_count; i++) {
   12375             sizes[i] = prefetch_size;
   12376         }
   12377 
   12378         regions[0].nr_sizes = prefetch_count;
   12379         regions[0].sizes = sizes;
   12380         regions[0].vmid = ION_FLAG_CP_PIXEL;
   12381 
   12382         prefetch_data->nr_regions = 1;
   12383         prefetch_data->regions = regions;
   12384         prefetch_data->heap_id = ION_HEAP(ION_SECURE_HEAP_ID);
   12385 
   12386         custom_data->cmd = ION_IOC_PREFETCH;
   12387         custom_data->arg = (unsigned long )prefetch_data;
   12388 
   12389         rc = ioctl(ion_fd, ION_IOC_CUSTOM, custom_data);
   12390         if (rc) {
   12391             DEBUG_PRINT_ERROR("Custom prefetch ioctl failed rc : %d, errno : %d\n", rc, errno);
   12392         }
   12393 
   12394 prefetch_exit:
   12395         close(ion_fd);
   12396         free(sizes);
   12397         free(regions);
   12398         free(prefetch_data);
   12399         free(custom_data);
   12400     }
   12401 }
   12402 
   12403 // No code beyond this !
   12404 
   12405 // inline import of vendor-extensions implementation
   12406 #include "omx_vdec_extensions.hpp"
   12407