Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (c) 2010 - 2014, The Linux Foundation. All rights reserved.
      3 
      4 Redistribution and use in source and binary forms, with or without
      5 modification, are permitted provided that the following conditions are met:
      6     * Redistributions of source code must retain the above copyright
      7       notice, this list of conditions and the following disclaimer.
      8     * Redistributions in binary form must reproduce the above copyright
      9       notice, this list of conditions and the following disclaimer in the
     10       documentation and/or other materials provided with the distribution.
     11     * Neither the name of The Linux Foundation nor
     12       the names of its contributors may be used to endorse or promote
     13       products derived from this software without specific prior written
     14       permission.
     15 
     16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
     17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
     19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
     20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
     21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
     22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
     23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
     25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
     26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     27 --------------------------------------------------------------------------*/
     28 
     29 /*============================================================================
     30                             O p e n M A X   w r a p p e r s
     31                              O p e n  M A X   C o r e
     32 
     33 *//** @file omx_vdec.cpp
     34   This module contains the implementation of the OpenMAX core & component.
     35 
     36 *//*========================================================================*/
     37 
     38 //////////////////////////////////////////////////////////////////////////////
     39 //                             Include Files
     40 //////////////////////////////////////////////////////////////////////////////
     41 
     42 #define __STDC_FORMAT_MACROS
     43 #include <inttypes.h>
     44 
     45 #include <string.h>
     46 #include <pthread.h>
     47 #include <sys/prctl.h>
     48 #include <stdlib.h>
     49 #include <unistd.h>
     50 #include <errno.h>
     51 #include "omx_vdec.h"
     52 #include <fcntl.h>
     53 #include <limits.h>
     54 #include <stdlib.h>
     55 #include <media/hardware/HardwareAPI.h>
     56 #include <media/msm_media_info.h>
     57 
     58 #ifndef _ANDROID_
     59 #include <sys/ioctl.h>
     60 #include <sys/mman.h>
     61 #endif //_ANDROID_
     62 
     63 #ifdef _ANDROID_
     64 #include <cutils/properties.h>
     65 #undef USE_EGL_IMAGE_GPU
     66 #endif
     67 
     68 #include <qdMetaData.h>
     69 
     70 #ifdef _ANDROID_
     71 #include "DivXDrmDecrypt.h"
     72 #endif //_ANDROID_
     73 
     74 #ifdef ANDROID_JELLYBEAN_MR2
     75 #include "QComOMXMetadata.h"
     76 #endif
     77 
     78 #ifdef USE_EGL_IMAGE_GPU
     79 #include <EGL/egl.h>
     80 #include <EGL/eglQCOM.h>
     81 #define EGL_BUFFER_HANDLE 0x4F00
     82 #define EGL_BUFFER_OFFSET 0x4F01
     83 #endif
     84 
     85 #define BUFFER_LOG_LOC "/data/misc/media"
     86 
     87 #ifdef OUTPUT_EXTRADATA_LOG
     88 FILE *outputExtradataFile;
     89 char output_extradata_filename [] = "/data/misc/media/extradata";
     90 #endif
     91 
     92 #define DEFAULT_FPS 30
     93 #define MAX_SUPPORTED_FPS 120
     94 #define DEFAULT_WIDTH_ALIGNMENT 128
     95 #define DEFAULT_HEIGHT_ALIGNMENT 32
     96 
     97 #define VC1_SP_MP_START_CODE        0xC5000000
     98 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
     99 #define VC1_AP_SEQ_START_CODE       0x0F010000
    100 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
    101 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
    102 #define VC1_SIMPLE_PROFILE          0
    103 #define VC1_MAIN_PROFILE            1
    104 #define VC1_ADVANCE_PROFILE         3
    105 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
    106 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
    107 #define VC1_STRUCT_C_LEN            4
    108 #define VC1_STRUCT_C_POS            8
    109 #define VC1_STRUCT_A_POS            12
    110 #define VC1_STRUCT_B_POS            24
    111 #define VC1_SEQ_LAYER_SIZE          36
    112 #define POLL_TIMEOUT 0x7fffffff
    113 
    114 #define MEM_DEVICE "/dev/ion"
    115 #define MEM_HEAP_ID ION_CP_MM_HEAP_ID
    116 
    117 #ifdef _ANDROID_
    118 extern "C" {
    119 #include<utils/Log.h>
    120 }
    121 #endif//_ANDROID_
    122 
    123 #define SZ_4K 0x1000
    124 #define SZ_1M 0x100000
    125 
    126 #define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
    127 #define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
    128 #define EXTRADATA_IDX(__num_planes) (__num_planes  - 1)
    129 #define ALIGN(x, to_align) ((((unsigned) x) + (to_align - 1)) & ~(to_align - 1))
    130 
    131 #define DEFAULT_EXTRADATA (OMX_INTERLACE_EXTRADATA)
    132 #define DEFAULT_CONCEAL_COLOR "32784" //0x8010, black by default
    133 
    134 
    135 static OMX_U32 maxSmoothStreamingWidth = 1920;
    136 static OMX_U32 maxSmoothStreamingHeight = 1088;
    137 
    138 void* async_message_thread (void *input)
    139 {
    140     OMX_BUFFERHEADERTYPE *buffer;
    141     struct v4l2_plane plane[VIDEO_MAX_PLANES];
    142     struct pollfd pfd;
    143     struct v4l2_buffer v4l2_buf;
    144     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
    145     struct v4l2_event dqevent;
    146     omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
    147     pfd.events = POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLRDBAND | POLLPRI;
    148     pfd.fd = omx->drv_ctx.video_driver_fd;
    149     int error_code = 0,rc=0,bytes_read = 0,bytes_written = 0;
    150     DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
    151     prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
    152     while (1) {
    153         rc = poll(&pfd, 1, POLL_TIMEOUT);
    154         if (!rc) {
    155             DEBUG_PRINT_ERROR("Poll timedout");
    156             break;
    157         } else if (rc < 0) {
    158             DEBUG_PRINT_ERROR("Error while polling: %d", rc);
    159             break;
    160         }
    161         if ((pfd.revents & POLLIN) || (pfd.revents & POLLRDNORM)) {
    162             struct vdec_msginfo vdec_msg;
    163             memset(&vdec_msg, 0, sizeof(vdec_msg));
    164             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    165             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    166             v4l2_buf.length = omx->drv_ctx.num_planes;
    167             v4l2_buf.m.planes = plane;
    168             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    169                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    170                 vdec_msg.status_code=VDEC_S_SUCCESS;
    171                 vdec_msg.msgdata.output_frame.client_data=(void*)&v4l2_buf;
    172                 vdec_msg.msgdata.output_frame.len=plane[0].bytesused;
    173                 vdec_msg.msgdata.output_frame.bufferaddr=(void*)plane[0].m.userptr;
    174                 vdec_msg.msgdata.output_frame.time_stamp= ((uint64_t)v4l2_buf.timestamp.tv_sec * (uint64_t)1000000) +
    175                     (uint64_t)v4l2_buf.timestamp.tv_usec;
    176                 if (vdec_msg.msgdata.output_frame.len) {
    177                     vdec_msg.msgdata.output_frame.framesize.left = plane[0].reserved[2];
    178                     vdec_msg.msgdata.output_frame.framesize.top = plane[0].reserved[3];
    179                     vdec_msg.msgdata.output_frame.framesize.right = plane[0].reserved[4];
    180                     vdec_msg.msgdata.output_frame.framesize.bottom = plane[0].reserved[5];
    181                     vdec_msg.msgdata.output_frame.picsize.frame_width = plane[0].reserved[6];
    182                     vdec_msg.msgdata.output_frame.picsize.frame_height = plane[0].reserved[7];
    183                 }
    184                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    185                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    186                     break;
    187                 }
    188             }
    189         }
    190         if ((pfd.revents & POLLOUT) || (pfd.revents & POLLWRNORM)) {
    191             struct vdec_msginfo vdec_msg;
    192             v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    193             v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    194             v4l2_buf.length = 1;
    195             v4l2_buf.m.planes = plane;
    196             while (!ioctl(pfd.fd, VIDIOC_DQBUF, &v4l2_buf)) {
    197                 vdec_msg.msgcode=VDEC_MSG_RESP_INPUT_BUFFER_DONE;
    198                 vdec_msg.status_code=VDEC_S_SUCCESS;
    199                 vdec_msg.msgdata.input_frame_clientdata=(void*)&v4l2_buf;
    200                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    201                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    202                     break;
    203                 }
    204             }
    205         }
    206         if (pfd.revents & POLLPRI) {
    207             rc = ioctl(pfd.fd, VIDIOC_DQEVENT, &dqevent);
    208             if (dqevent.type == V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT ) {
    209                 struct vdec_msginfo vdec_msg;
    210                 vdec_msg.msgcode=VDEC_MSG_EVT_CONFIG_CHANGED;
    211                 vdec_msg.status_code=VDEC_S_SUCCESS;
    212                 DEBUG_PRINT_HIGH("VIDC Port Reconfig recieved insufficient");
    213                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    214                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    215                     break;
    216                 }
    217             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_FLUSH_DONE) {
    218                 struct vdec_msginfo vdec_msg;
    219                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_INPUT_DONE;
    220                 vdec_msg.status_code=VDEC_S_SUCCESS;
    221                 DEBUG_PRINT_HIGH("VIDC Input Flush Done Recieved");
    222                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    223                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    224                     break;
    225                 }
    226                 vdec_msg.msgcode=VDEC_MSG_RESP_FLUSH_OUTPUT_DONE;
    227                 vdec_msg.status_code=VDEC_S_SUCCESS;
    228                 DEBUG_PRINT_HIGH("VIDC Output Flush Done Recieved");
    229                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    230                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    231                     break;
    232                 }
    233             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_CLOSE_DONE) {
    234                 DEBUG_PRINT_HIGH("VIDC Close Done Recieved and async_message_thread Exited");
    235                 break;
    236             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_OVERLOAD) {
    237                 struct vdec_msginfo vdec_msg;
    238                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_OVERLOAD;
    239                 vdec_msg.status_code=VDEC_S_SUCCESS;
    240                 DEBUG_PRINT_ERROR("HW Overload received");
    241                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    242                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    243                     break;
    244                 }
    245             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED) {
    246                 struct vdec_msginfo vdec_msg;
    247                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_UNSUPPORTED;
    248                 vdec_msg.status_code=VDEC_S_SUCCESS;
    249                 DEBUG_PRINT_ERROR("HW Unsupported received");
    250                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    251                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    252                     break;
    253                 }
    254             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_SYS_ERROR) {
    255                 struct vdec_msginfo vdec_msg;
    256                 vdec_msg.msgcode=VDEC_MSG_EVT_HW_ERROR;
    257                 vdec_msg.status_code=VDEC_S_SUCCESS;
    258                 DEBUG_PRINT_HIGH("SYS Error Recieved");
    259                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    260                     DEBUG_PRINT_HIGH("async_message_thread Exited");
    261                     break;
    262                 }
    263             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE) {
    264                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    265 
    266                 DEBUG_PRINT_LOW("REFERENCE RELEASE EVENT RECVD fd = %d offset = %d", ptr[0], ptr[1]);
    267                 omx->buf_ref_remove(ptr[0], ptr[1]);
    268             } else if (dqevent.type == V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER) {
    269                 unsigned int *ptr = (unsigned int *)(void *)dqevent.u.data;
    270                 struct vdec_msginfo vdec_msg;
    271 
    272                 DEBUG_PRINT_LOW("Release unqueued buffer event recvd fd = %d offset = %d", ptr[0], ptr[1]);
    273 
    274                 v4l2_buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    275                 v4l2_buf.memory = V4L2_MEMORY_USERPTR;
    276                 v4l2_buf.length = omx->drv_ctx.num_planes;
    277                 v4l2_buf.m.planes = plane;
    278                 v4l2_buf.index = ptr[5];
    279                 v4l2_buf.flags = 0;
    280 
    281                 vdec_msg.msgcode=VDEC_MSG_RESP_OUTPUT_BUFFER_DONE;
    282                 vdec_msg.status_code=VDEC_S_SUCCESS;
    283                 vdec_msg.msgdata.output_frame.client_data = (void*)&v4l2_buf;
    284                 vdec_msg.msgdata.output_frame.len = 0;
    285                 vdec_msg.msgdata.output_frame.bufferaddr = (void*)(intptr_t)ptr[2];
    286                 vdec_msg.msgdata.output_frame.time_stamp = ((uint64_t)ptr[3] * (uint64_t)1000000) +
    287                     (uint64_t)ptr[4];
    288                 if (omx->async_message_process(input,&vdec_msg) < 0) {
    289                     DEBUG_PRINT_HIGH("async_message_thread Exitedn");
    290                     break;
    291                 }
    292             }
    293             else {
    294                 DEBUG_PRINT_HIGH("VIDC Some Event recieved");
    295                 continue;
    296             }
    297         }
    298     }
    299     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
    300     return NULL;
    301 }
    302 
    303 void* message_thread(void *input)
    304 {
    305     omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
    306     unsigned char id;
    307     int n;
    308 
    309     DEBUG_PRINT_HIGH("omx_vdec: message thread start");
    310     prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
    311     while (1) {
    312 
    313         n = read(omx->m_pipe_in, &id, 1);
    314 
    315         if (0 == n) {
    316             break;
    317         }
    318 
    319         if (1 == n) {
    320             omx->process_event_cb(omx, id);
    321         }
    322         if ((n < 0) && (errno != EINTR)) {
    323             DEBUG_PRINT_LOW("ERROR: read from pipe failed, ret %d errno %d", n, errno);
    324             break;
    325         }
    326     }
    327     DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
    328     return 0;
    329 }
    330 
    331 void post_message(omx_vdec *omx, unsigned char id)
    332 {
    333     int ret_value;
    334     DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
    335     ret_value = write(omx->m_pipe_out, &id, 1);
    336     DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
    337 }
    338 
    339 // omx_cmd_queue destructor
    340 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    341 {
    342     // Nothing to do
    343 }
    344 
    345 // omx cmd queue constructor
    346 omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
    347 {
    348     memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
    349 }
    350 
    351 // omx cmd queue insert
    352 bool omx_vdec::omx_cmd_queue::insert_entry(unsigned long p1, unsigned long p2, unsigned long id)
    353 {
    354     bool ret = true;
    355     if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
    356         m_q[m_write].id       = id;
    357         m_q[m_write].param1   = p1;
    358         m_q[m_write].param2   = p2;
    359         m_write++;
    360         m_size ++;
    361         if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    362             m_write = 0;
    363         }
    364     } else {
    365         ret = false;
    366         DEBUG_PRINT_ERROR("ERROR: %s()::Command Queue Full", __func__);
    367     }
    368     return ret;
    369 }
    370 
    371 // omx cmd queue pop
    372 bool omx_vdec::omx_cmd_queue::pop_entry(unsigned long *p1, unsigned long *p2, unsigned long *id)
    373 {
    374     bool ret = true;
    375     if (m_size > 0) {
    376         *id = m_q[m_read].id;
    377         *p1 = m_q[m_read].param1;
    378         *p2 = m_q[m_read].param2;
    379         // Move the read pointer ahead
    380         ++m_read;
    381         --m_size;
    382         if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
    383             m_read = 0;
    384         }
    385     } else {
    386         ret = false;
    387     }
    388     return ret;
    389 }
    390 
    391 // Retrieve the first mesg type in the queue
    392 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    393 {
    394     return m_q[m_read].id;
    395 }
    396 
    397 #ifdef _ANDROID_
    398 omx_vdec::ts_arr_list::ts_arr_list()
    399 {
    400     //initialize timestamps array
    401     memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
    402 }
    403 omx_vdec::ts_arr_list::~ts_arr_list()
    404 {
    405     //free m_ts_arr_list?
    406 }
    407 
    408 bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
    409 {
    410     bool ret = true;
    411     bool duplicate_ts = false;
    412     int idx = 0;
    413 
    414     //insert at the first available empty location
    415     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    416         if (!m_ts_arr_list[idx].valid) {
    417             //found invalid or empty entry, save timestamp
    418             m_ts_arr_list[idx].valid = true;
    419             m_ts_arr_list[idx].timestamp = ts;
    420             DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
    421                     ts, idx);
    422             break;
    423         }
    424     }
    425 
    426     if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
    427         DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
    428         ret = false;
    429     }
    430     return ret;
    431 }
    432 
    433 bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
    434 {
    435     bool ret = true;
    436     int min_idx = -1;
    437     OMX_TICKS min_ts = 0;
    438     int idx = 0;
    439 
    440     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    441 
    442         if (m_ts_arr_list[idx].valid) {
    443             //found valid entry, save index
    444             if (min_idx < 0) {
    445                 //first valid entry
    446                 min_ts = m_ts_arr_list[idx].timestamp;
    447                 min_idx = idx;
    448             } else if (m_ts_arr_list[idx].timestamp < min_ts) {
    449                 min_ts = m_ts_arr_list[idx].timestamp;
    450                 min_idx = idx;
    451             }
    452         }
    453 
    454     }
    455 
    456     if (min_idx < 0) {
    457         //no valid entries found
    458         DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
    459         ts = 0;
    460         ret = false;
    461     } else {
    462         ts = m_ts_arr_list[min_idx].timestamp;
    463         m_ts_arr_list[min_idx].valid = false;
    464         DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
    465                 ts, min_idx);
    466     }
    467 
    468     return ret;
    469 
    470 }
    471 
    472 
    473 bool omx_vdec::ts_arr_list::reset_ts_list()
    474 {
    475     bool ret = true;
    476     int idx = 0;
    477 
    478     DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
    479     for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
    480         m_ts_arr_list[idx].valid = false;
    481     }
    482     return ret;
    483 }
    484 #endif
    485 
    486 // factory function executed by the core to create instances
    487 void *get_omx_component_factory_fn(void)
    488 {
    489     return (new omx_vdec);
    490 }
    491 
    492 #ifdef _ANDROID_
    493 #ifdef USE_ION
    494 VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
    495         ion_user_handle_t handle, int ionMapfd)
    496 {
    497     (void) devicefd;
    498     (void) size;
    499     (void) base;
    500     (void) handle;
    501     (void) ionMapfd;
    502     //    ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
    503 }
    504 #else
    505 VideoHeap::VideoHeap(int fd, size_t size, void* base)
    506 {
    507     // dup file descriptor, map once, use pmem
    508     init(dup(fd), base, size, 0 , MEM_DEVICE);
    509 }
    510 #endif
    511 #endif // _ANDROID_
    512 /* ======================================================================
    513    FUNCTION
    514    omx_vdec::omx_vdec
    515 
    516    DESCRIPTION
    517    Constructor
    518 
    519    PARAMETERS
    520    None
    521 
    522    RETURN VALUE
    523    None.
    524    ========================================================================== */
    525 omx_vdec::omx_vdec(): m_error_propogated(false),
    526     m_state(OMX_StateInvalid),
    527     m_app_data(NULL),
    528     m_inp_mem_ptr(NULL),
    529     m_out_mem_ptr(NULL),
    530     input_flush_progress (false),
    531     output_flush_progress (false),
    532     input_use_buffer (false),
    533     output_use_buffer (false),
    534     ouput_egl_buffers(false),
    535     m_use_output_pmem(OMX_FALSE),
    536     m_out_mem_region_smi(OMX_FALSE),
    537     m_out_pvt_entry_pmem(OMX_FALSE),
    538     pending_input_buffers(0),
    539     pending_output_buffers(0),
    540     m_out_bm_count(0),
    541     m_inp_bm_count(0),
    542     m_inp_bPopulated(OMX_FALSE),
    543     m_out_bPopulated(OMX_FALSE),
    544     m_flags(0),
    545 #ifdef _ANDROID_
    546     m_heap_ptr(NULL),
    547 #endif
    548     m_inp_bEnabled(OMX_TRUE),
    549     m_out_bEnabled(OMX_TRUE),
    550     m_in_alloc_cnt(0),
    551     m_platform_list(NULL),
    552     m_platform_entry(NULL),
    553     m_pmem_info(NULL),
    554     h264_parser(NULL),
    555     arbitrary_bytes (true),
    556     psource_frame (NULL),
    557     pdest_frame (NULL),
    558     m_inp_heap_ptr (NULL),
    559     m_phdr_pmem_ptr(NULL),
    560     m_heap_inp_bm_count (0),
    561     codec_type_parse ((codec_type)0),
    562     first_frame_meta (true),
    563     frame_count (0),
    564     nal_count (0),
    565     nal_length(0),
    566     look_ahead_nal (false),
    567     first_frame(0),
    568     first_buffer(NULL),
    569     first_frame_size (0),
    570     m_device_file_ptr(NULL),
    571     m_vc1_profile((vc1_profile_type)0),
    572     h264_last_au_ts(LLONG_MAX),
    573     h264_last_au_flags(0),
    574     m_disp_hor_size(0),
    575     m_disp_vert_size(0),
    576     prev_ts(LLONG_MAX),
    577     rst_prev_ts(true),
    578     frm_int(0),
    579     in_reconfig(false),
    580     m_display_id(NULL),
    581     client_extradata(0),
    582     m_reject_avc_1080p_mp (0),
    583 #ifdef _ANDROID_
    584     m_enable_android_native_buffers(OMX_FALSE),
    585     m_use_android_native_buffers(OMX_FALSE),
    586     iDivXDrmDecrypt(NULL),
    587 #endif
    588     m_desc_buffer_ptr(NULL),
    589     secure_mode(false),
    590     m_other_extradata(NULL),
    591     m_profile(0),
    592     client_set_fps(false),
    593     m_last_rendered_TS(-1),
    594     m_queued_codec_config_count(0),
    595     secure_scaling_to_non_secure_opb(false)
    596 {
    597     /* Assumption is that , to begin with , we have all the frames with decoder */
    598     DEBUG_PRINT_HIGH("In %u bit OMX vdec Constructor", (unsigned int)sizeof(long) * 8);
    599     memset(&m_debug,0,sizeof(m_debug));
    600 #ifdef _ANDROID_
    601     char property_value[PROPERTY_VALUE_MAX] = {0};
    602     property_get("vidc.debug.level", property_value, "1");
    603     debug_level = atoi(property_value);
    604     property_value[0] = '\0';
    605 
    606     DEBUG_PRINT_HIGH("In OMX vdec Constructor");
    607 
    608     property_get("vidc.dec.debug.perf", property_value, "0");
    609     perf_flag = atoi(property_value);
    610     if (perf_flag) {
    611         DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
    612         dec_time.start();
    613         proc_frms = latency = 0;
    614     }
    615     prev_n_filled_len = 0;
    616     property_value[0] = '\0';
    617     property_get("vidc.dec.debug.ts", property_value, "0");
    618     m_debug_timestamp = atoi(property_value);
    619     DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
    620     if (m_debug_timestamp) {
    621         time_stamp_dts.set_timestamp_reorder_mode(true);
    622         time_stamp_dts.enable_debug_print(true);
    623     }
    624 
    625     property_value[0] = '\0';
    626     property_get("vidc.dec.debug.concealedmb", property_value, "0");
    627     m_debug_concealedmb = atoi(property_value);
    628     DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
    629 
    630     property_value[0] = '\0';
    631     property_get("vidc.dec.profile.check", property_value, "0");
    632     m_reject_avc_1080p_mp = atoi(property_value);
    633     DEBUG_PRINT_HIGH("vidc.dec.profile.check value is %d",m_reject_avc_1080p_mp);
    634 
    635     property_value[0] = '\0';
    636     property_get("vidc.dec.log.in", property_value, "0");
    637     m_debug.in_buffer_log = atoi(property_value);
    638 
    639     property_value[0] = '\0';
    640     property_get("vidc.dec.log.out", property_value, "0");
    641     m_debug.out_buffer_log = atoi(property_value);
    642     sprintf(m_debug.log_loc, "%s", BUFFER_LOG_LOC);
    643 
    644     property_value[0] = '\0';
    645     property_get("vidc.log.loc", property_value, "");
    646     if (*property_value)
    647         strlcpy(m_debug.log_loc, property_value, PROPERTY_VALUE_MAX);
    648 
    649     property_value[0] = '\0';
    650     property_get("vidc.dec.120fps.enabled", property_value, "0");
    651 
    652     //if this feature is not enabled then reset this value -ve
    653     if(atoi(property_value)) {
    654         DEBUG_PRINT_LOW("feature 120 FPS decode enabled");
    655         m_last_rendered_TS = 0;
    656     }
    657 
    658     property_value[0] = '\0';
    659     property_get("vidc.dec.debug.dyn.disabled", property_value, "0");
    660     m_disable_dynamic_buf_mode = atoi(property_value);
    661     DEBUG_PRINT_HIGH("vidc.dec.debug.dyn.disabled value is %d",m_disable_dynamic_buf_mode);
    662 
    663 #endif
    664     memset(&m_cmp,0,sizeof(m_cmp));
    665     memset(&m_cb,0,sizeof(m_cb));
    666     memset (&drv_ctx,0,sizeof(drv_ctx));
    667     memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
    668     memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
    669     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
    670     memset(&m_custom_buffersize, 0, sizeof(m_custom_buffersize));
    671     m_demux_entries = 0;
    672     msg_thread_id = 0;
    673     async_thread_id = 0;
    674     msg_thread_created = false;
    675     async_thread_created = false;
    676 #ifdef _ANDROID_ICS_
    677     memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
    678 #endif
    679     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
    680 
    681     /* invalidate m_frame_pack_arrangement */
    682     memset(&m_frame_pack_arrangement, 0, sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
    683     m_frame_pack_arrangement.cancel_flag = 1;
    684 
    685     drv_ctx.timestamp_adjust = false;
    686     drv_ctx.video_driver_fd = -1;
    687     m_vendor_config.pData = NULL;
    688     pthread_mutex_init(&m_lock, NULL);
    689     pthread_mutex_init(&c_lock, NULL);
    690     sem_init(&m_cmd_lock,0,0);
    691     sem_init(&m_safe_flush, 0, 0);
    692     streaming[CAPTURE_PORT] =
    693         streaming[OUTPUT_PORT] = false;
    694 #ifdef _ANDROID_
    695     char extradata_value[PROPERTY_VALUE_MAX] = {0};
    696     property_get("vidc.dec.debug.extradata", extradata_value, "0");
    697     m_debug_extradata = atoi(extradata_value);
    698     DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
    699 #endif
    700     m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
    701     client_buffers.set_vdec_client(this);
    702     dynamic_buf_mode = false;
    703     out_dynamic_list = NULL;
    704     is_down_scalar_enabled = false;
    705     m_smoothstreaming_mode = false;
    706     m_smoothstreaming_width = 0;
    707     m_smoothstreaming_height = 0;
    708     is_q6_platform = false;
    709 }
    710 
    711 static const int event_type[] = {
    712     V4L2_EVENT_MSM_VIDC_FLUSH_DONE,
    713     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_SUFFICIENT,
    714     V4L2_EVENT_MSM_VIDC_PORT_SETTINGS_CHANGED_INSUFFICIENT,
    715     V4L2_EVENT_MSM_VIDC_RELEASE_BUFFER_REFERENCE,
    716     V4L2_EVENT_MSM_VIDC_RELEASE_UNQUEUED_BUFFER,
    717     V4L2_EVENT_MSM_VIDC_CLOSE_DONE,
    718     V4L2_EVENT_MSM_VIDC_SYS_ERROR,
    719     V4L2_EVENT_MSM_VIDC_HW_OVERLOAD,
    720     V4L2_EVENT_MSM_VIDC_HW_UNSUPPORTED
    721 };
    722 
    723 static OMX_ERRORTYPE subscribe_to_events(int fd)
    724 {
    725     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    726     struct v4l2_event_subscription sub;
    727     int array_sz = sizeof(event_type)/sizeof(int);
    728     int i,rc;
    729     if (fd < 0) {
    730         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    731         return OMX_ErrorBadParameter;
    732     }
    733 
    734     for (i = 0; i < array_sz; ++i) {
    735         memset(&sub, 0, sizeof(sub));
    736         sub.type = event_type[i];
    737         rc = ioctl(fd, VIDIOC_SUBSCRIBE_EVENT, &sub);
    738         if (rc) {
    739             DEBUG_PRINT_ERROR("Failed to subscribe event: 0x%x", sub.type);
    740             break;
    741         }
    742     }
    743     if (i < array_sz) {
    744         for (--i; i >=0 ; i--) {
    745             memset(&sub, 0, sizeof(sub));
    746             sub.type = event_type[i];
    747             rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    748             if (rc)
    749                 DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    750         }
    751         eRet = OMX_ErrorNotImplemented;
    752     }
    753     return eRet;
    754 }
    755 
    756 
    757 static OMX_ERRORTYPE unsubscribe_to_events(int fd)
    758 {
    759     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    760     struct v4l2_event_subscription sub;
    761     int array_sz = sizeof(event_type)/sizeof(int);
    762     int i,rc;
    763     if (fd < 0) {
    764         DEBUG_PRINT_ERROR("Invalid input: %d", fd);
    765         return OMX_ErrorBadParameter;
    766     }
    767 
    768     for (i = 0; i < array_sz; ++i) {
    769         memset(&sub, 0, sizeof(sub));
    770         sub.type = event_type[i];
    771         rc = ioctl(fd, VIDIOC_UNSUBSCRIBE_EVENT, &sub);
    772         if (rc) {
    773             DEBUG_PRINT_ERROR("Failed to unsubscribe event: 0x%x", sub.type);
    774             break;
    775         }
    776     }
    777     return eRet;
    778 }
    779 
    780 /* ======================================================================
    781    FUNCTION
    782    omx_vdec::~omx_vdec
    783 
    784    DESCRIPTION
    785    Destructor
    786 
    787    PARAMETERS
    788    None
    789 
    790    RETURN VALUE
    791    None.
    792    ========================================================================== */
    793 omx_vdec::~omx_vdec()
    794 {
    795     m_pmem_info = NULL;
    796     struct v4l2_decoder_cmd dec;
    797     DEBUG_PRINT_HIGH("In OMX vdec Destructor");
    798     if (m_pipe_in) close(m_pipe_in);
    799     if (m_pipe_out) close(m_pipe_out);
    800     m_pipe_in = -1;
    801     m_pipe_out = -1;
    802     DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
    803     if (msg_thread_created)
    804         pthread_join(msg_thread_id,NULL);
    805     DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
    806     dec.cmd = V4L2_DEC_CMD_STOP;
    807     if (drv_ctx.video_driver_fd >=0 ) {
    808         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec))
    809             DEBUG_PRINT_ERROR("STOP Command failed");
    810     }
    811     if (async_thread_created)
    812         pthread_join(async_thread_id,NULL);
    813     unsubscribe_to_events(drv_ctx.video_driver_fd);
    814     close(drv_ctx.video_driver_fd);
    815     pthread_mutex_destroy(&m_lock);
    816     pthread_mutex_destroy(&c_lock);
    817     sem_destroy(&m_cmd_lock);
    818     if (perf_flag) {
    819         DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
    820         dec_time.end();
    821     }
    822     DEBUG_PRINT_INFO("Exit OMX vdec Destructor: fd=%d",drv_ctx.video_driver_fd);
    823 }
    824 
    825 int release_buffers(omx_vdec* obj, enum vdec_buffer buffer_type)
    826 {
    827     struct v4l2_requestbuffers bufreq;
    828     int rc = 0;
    829     if (buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
    830         bufreq.memory = V4L2_MEMORY_USERPTR;
    831         bufreq.count = 0;
    832         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
    833         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    834     } else if(buffer_type == VDEC_BUFFER_TYPE_INPUT) {
    835         bufreq.memory = V4L2_MEMORY_USERPTR;
    836         bufreq.count = 0;
    837         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
    838         rc = ioctl(obj->drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
    839     }
    840     return rc;
    841 }
    842 
    843 /* ======================================================================
    844    FUNCTION
    845    omx_vdec::OMXCntrlProcessMsgCb
    846 
    847    DESCRIPTION
    848    IL Client callbacks are generated through this routine. The decoder
    849    provides the thread context for this routine.
    850 
    851    PARAMETERS
    852    ctxt -- Context information related to the self.
    853    id   -- Event identifier. This could be any of the following:
    854    1. Command completion event
    855    2. Buffer done callback event
    856    3. Frame done callback event
    857 
    858    RETURN VALUE
    859    None.
    860 
    861    ========================================================================== */
    862 void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
    863 {
    864     unsigned long p1; // Parameter - 1
    865     unsigned long p2; // Parameter - 2
    866     unsigned long ident;
    867     unsigned qsize=0; // qsize
    868     omx_vdec *pThis = (omx_vdec *) ctxt;
    869 
    870     if (!pThis) {
    871         DEBUG_PRINT_ERROR("ERROR: %s()::Context is incorrect, bailing out",
    872                 __func__);
    873         return;
    874     }
    875 
    876     // Protect the shared queue data structure
    877     do {
    878         /*Read the message id's from the queue*/
    879         pthread_mutex_lock(&pThis->m_lock);
    880         qsize = pThis->m_cmd_q.m_size;
    881         if (qsize) {
    882             pThis->m_cmd_q.pop_entry(&p1, &p2, &ident);
    883         }
    884 
    885         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
    886             qsize = pThis->m_ftb_q.m_size;
    887             if (qsize) {
    888                 pThis->m_ftb_q.pop_entry(&p1, &p2, &ident);
    889             }
    890         }
    891 
    892         if (qsize == 0 && pThis->m_state != OMX_StatePause) {
    893             qsize = pThis->m_etb_q.m_size;
    894             if (qsize) {
    895                 pThis->m_etb_q.pop_entry(&p1, &p2, &ident);
    896             }
    897         }
    898         pthread_mutex_unlock(&pThis->m_lock);
    899 
    900         /*process message if we have one*/
    901         if (qsize > 0) {
    902             id = ident;
    903             switch (id) {
    904                 case OMX_COMPONENT_GENERATE_EVENT:
    905                     if (pThis->m_cb.EventHandler) {
    906                         switch (p1) {
    907                             case OMX_CommandStateSet:
    908                                 pThis->m_state = (OMX_STATETYPE) p2;
    909                                 DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
    910                                         pThis->m_state);
    911                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    912                                         OMX_EventCmdComplete, p1, p2, NULL);
    913                                 break;
    914 
    915                             case OMX_EventError:
    916                                 if (p2 == OMX_StateInvalid) {
    917                                     DEBUG_PRINT_ERROR("OMX_EventError: p2 is OMX_StateInvalid");
    918                                     pThis->m_state = (OMX_STATETYPE) p2;
    919                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    920                                             OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
    921                                 } else if (p2 == (unsigned long)OMX_ErrorHardware) {
    922                                     pThis->omx_report_error();
    923                                 } else {
    924                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    925                                             OMX_EventError, p2, (OMX_U32)NULL, NULL );
    926                                 }
    927                                 break;
    928 
    929                             case OMX_CommandPortDisable:
    930                                 DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%lu]", p2);
    931                                 if (BITMASK_PRESENT(&pThis->m_flags,
    932                                             OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
    933                                     BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
    934                                     break;
    935                                 }
    936                                 if (p2 == OMX_CORE_OUTPUT_PORT_INDEX) {
    937                                     OMX_ERRORTYPE eRet = OMX_ErrorNone;
    938                                     pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
    939                                     if (release_buffers(pThis, VDEC_BUFFER_TYPE_OUTPUT))
    940                                         DEBUG_PRINT_HIGH("Failed to release output buffers");
    941                                     OMX_ERRORTYPE eRet1 = pThis->get_buffer_req(&pThis->drv_ctx.op_buf);
    942                                     pThis->in_reconfig = false;
    943                                     if (eRet !=  OMX_ErrorNone) {
    944                                         DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
    945                                         pThis->omx_report_error();
    946                                         break;
    947                                     }
    948                                 }
    949                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    950                                         OMX_EventCmdComplete, p1, p2, NULL );
    951                                 break;
    952                             case OMX_CommandPortEnable:
    953                                 DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%lu]", p2);
    954                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
    955                                         OMX_EventCmdComplete, p1, p2, NULL );
    956                                 break;
    957 
    958                             default:
    959                                 pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
    960                                         OMX_EventCmdComplete, p1, p2, NULL );
    961                                 break;
    962 
    963                         }
    964                     } else {
    965                         DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
    966                     }
    967                     break;
    968                 case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
    969                     if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
    970                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
    971                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy_arbitrary failure");
    972                         pThis->omx_report_error ();
    973                     }
    974                     break;
    975                 case OMX_COMPONENT_GENERATE_ETB: {
    976                         OMX_ERRORTYPE iret;
    977                         iret = pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1, (OMX_BUFFERHEADERTYPE *)p2);
    978                         if (iret == OMX_ErrorInsufficientResources) {
    979                             DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure due to HW overload");
    980                             pThis->omx_report_hw_overload ();
    981                         } else if (iret != OMX_ErrorNone) {
    982                         DEBUG_PRINT_ERROR("empty_this_buffer_proxy failure");
    983                         pThis->omx_report_error ();
    984                     }
    985                     }
    986                     break;
    987 
    988                 case OMX_COMPONENT_GENERATE_FTB:
    989                     if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)(intptr_t)p1,\
    990                                 (OMX_BUFFERHEADERTYPE *)(intptr_t)p2) != OMX_ErrorNone) {
    991                         DEBUG_PRINT_ERROR("fill_this_buffer_proxy failure");
    992                         pThis->omx_report_error ();
    993                     }
    994                     break;
    995 
    996                 case OMX_COMPONENT_GENERATE_COMMAND:
    997                     pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
    998                             (OMX_U32)p2,(OMX_PTR)NULL);
    999                     break;
   1000 
   1001                 case OMX_COMPONENT_GENERATE_EBD:
   1002 
   1003                     if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
   1004                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EBD failure");
   1005                         pThis->omx_report_error ();
   1006                     } else {
   1007                         if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
   1008                             pThis->time_stamp_dts.remove_time_stamp(
   1009                                     ((OMX_BUFFERHEADERTYPE *)(intptr_t)p1)->nTimeStamp,
   1010                                     (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1011                                     ?true:false);
   1012                         }
   1013                         if ( pThis->empty_buffer_done(&pThis->m_cmp,
   1014                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone) {
   1015                             DEBUG_PRINT_ERROR("empty_buffer_done failure");
   1016                             pThis->omx_report_error ();
   1017                         }
   1018                     }
   1019                     break;
   1020                 case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED: {
   1021                                             int64_t *timestamp = (int64_t *)(intptr_t)p1;
   1022                                             if (p1) {
   1023                                                 pThis->time_stamp_dts.remove_time_stamp(*timestamp,
   1024                                                         (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   1025                                                         ?true:false);
   1026                                                 free(timestamp);
   1027                                             }
   1028                                         }
   1029                                         break;
   1030                 case OMX_COMPONENT_GENERATE_FBD:
   1031                                         if (p2 != VDEC_S_SUCCESS) {
   1032                                             DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_FBD failure");
   1033                                             pThis->omx_report_error ();
   1034                                         } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
   1035                                                     (OMX_BUFFERHEADERTYPE *)(intptr_t)p1) != OMX_ErrorNone ) {
   1036                                             DEBUG_PRINT_ERROR("fill_buffer_done failure");
   1037                                             pThis->omx_report_error ();
   1038                                         }
   1039                                         break;
   1040 
   1041                 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
   1042                                         DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
   1043                                         if (!pThis->input_flush_progress) {
   1044                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1045                                         } else {
   1046                                             pThis->execute_input_flush();
   1047                                             if (pThis->m_cb.EventHandler) {
   1048                                                 if (p2 != VDEC_S_SUCCESS) {
   1049                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
   1050                                                     pThis->omx_report_error ();
   1051                                                 } else {
   1052                                                     /*Check if we need generate event for Flush done*/
   1053                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1054                                                                 OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
   1055                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
   1056                                                         DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
   1057                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1058                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
   1059                                                                 OMX_CORE_INPUT_PORT_INDEX,NULL );
   1060                                                     }
   1061                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1062                                                                 OMX_COMPONENT_IDLE_PENDING)) {
   1063                                                         if (pThis->stream_off(OMX_CORE_INPUT_PORT_INDEX)) {
   1064                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on OUTPUT Port");
   1065                                                             pThis->omx_report_error ();
   1066                                                         } else {
   1067                                                             pThis->streaming[OUTPUT_PORT] = false;
   1068                                                         }
   1069                                                         if (!pThis->output_flush_progress) {
   1070                                                             DEBUG_PRINT_LOW("Input flush done hence issue stop");
   1071                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1072                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1073                                                         }
   1074                                                     }
   1075                                                 }
   1076                                             } else {
   1077                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1078                                             }
   1079                                         }
   1080                                         break;
   1081 
   1082                 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
   1083                                         DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
   1084                                         if (!pThis->output_flush_progress) {
   1085                                             DEBUG_PRINT_HIGH("WARNING: Unexpected flush from driver");
   1086                                         } else {
   1087                                             pThis->execute_output_flush();
   1088                                             if (pThis->m_cb.EventHandler) {
   1089                                                 if (p2 != VDEC_S_SUCCESS) {
   1090                                                     DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
   1091                                                     pThis->omx_report_error ();
   1092                                                 } else {
   1093                                                     /*Check if we need generate event for Flush done*/
   1094                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1095                                                                 OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
   1096                                                         DEBUG_PRINT_LOW("Notify Output Flush done");
   1097                                                         BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   1098                                                         pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1099                                                                 OMX_EventCmdComplete,OMX_CommandFlush,
   1100                                                                 OMX_CORE_OUTPUT_PORT_INDEX,NULL );
   1101                                                     }
   1102                                                     if (BITMASK_PRESENT(&pThis->m_flags,
   1103                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
   1104                                                         DEBUG_PRINT_LOW("Internal flush complete");
   1105                                                         BITMASK_CLEAR (&pThis->m_flags,
   1106                                                                 OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   1107                                                         if (BITMASK_PRESENT(&pThis->m_flags,
   1108                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
   1109                                                             pThis->post_event(OMX_CommandPortDisable,
   1110                                                                     OMX_CORE_OUTPUT_PORT_INDEX,
   1111                                                                     OMX_COMPONENT_GENERATE_EVENT);
   1112                                                             BITMASK_CLEAR (&pThis->m_flags,
   1113                                                                     OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
   1114                                                             BITMASK_CLEAR (&pThis->m_flags,
   1115                                                                     OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   1116 
   1117                                                         }
   1118                                                     }
   1119 
   1120                                                     if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
   1121                                                         if (pThis->stream_off(OMX_CORE_OUTPUT_PORT_INDEX)) {
   1122                                                             DEBUG_PRINT_ERROR("Failed to call streamoff on CAPTURE Port");
   1123                                                             pThis->omx_report_error ();
   1124                                                             break;
   1125                                                         }
   1126                                                         pThis->streaming[CAPTURE_PORT] = false;
   1127                                                         if (!pThis->input_flush_progress) {
   1128                                                             DEBUG_PRINT_LOW("Output flush done hence issue stop");
   1129                                                             pThis->post_event ((unsigned int)NULL, VDEC_S_SUCCESS,\
   1130                                                                     OMX_COMPONENT_GENERATE_STOP_DONE);
   1131                                                         }
   1132                                                     }
   1133                                                 }
   1134                                             } else {
   1135                                                 DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1136                                             }
   1137                                         }
   1138                                         break;
   1139 
   1140                 case OMX_COMPONENT_GENERATE_START_DONE:
   1141                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
   1142 
   1143                                         if (pThis->m_cb.EventHandler) {
   1144                                             if (p2 != VDEC_S_SUCCESS) {
   1145                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_START_DONE Failure");
   1146                                                 pThis->omx_report_error ();
   1147                                             } else {
   1148                                                 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
   1149                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1150                                                     DEBUG_PRINT_LOW("Move to executing");
   1151                                                     // Send the callback now
   1152                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1153                                                     pThis->m_state = OMX_StateExecuting;
   1154                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1155                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1156                                                             OMX_StateExecuting, NULL);
   1157                                                 } else if (BITMASK_PRESENT(&pThis->m_flags,
   1158                                                             OMX_COMPONENT_PAUSE_PENDING)) {
   1159                                                     if (/*ioctl (pThis->drv_ctx.video_driver_fd,
   1160                                                           VDEC_IOCTL_CMD_PAUSE,NULL ) < */0) {
   1161                                                         DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_PAUSE failed");
   1162                                                         pThis->omx_report_error ();
   1163                                                     }
   1164                                                 }
   1165                                             }
   1166                                         } else {
   1167                                             DEBUG_PRINT_LOW("Event Handler callback is NULL");
   1168                                         }
   1169                                         break;
   1170 
   1171                 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
   1172                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
   1173                                         if (pThis->m_cb.EventHandler) {
   1174                                             if (p2 != VDEC_S_SUCCESS) {
   1175                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
   1176                                                 pThis->omx_report_error ();
   1177                                             } else {
   1178                                                 pThis->complete_pending_buffer_done_cbs();
   1179                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
   1180                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
   1181                                                     //Send the callback now
   1182                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
   1183                                                     pThis->m_state = OMX_StatePause;
   1184                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1185                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1186                                                             OMX_StatePause, NULL);
   1187                                                 }
   1188                                             }
   1189                                         } else {
   1190                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1191                                         }
   1192 
   1193                                         break;
   1194 
   1195                 case OMX_COMPONENT_GENERATE_RESUME_DONE:
   1196                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
   1197                                         if (pThis->m_cb.EventHandler) {
   1198                                             if (p2 != VDEC_S_SUCCESS) {
   1199                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_RESUME_DONE failed");
   1200                                                 pThis->omx_report_error ();
   1201                                             } else {
   1202                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
   1203                                                     DEBUG_PRINT_LOW("Moving the decoder to execute state");
   1204                                                     // Send the callback now
   1205                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
   1206                                                     pThis->m_state = OMX_StateExecuting;
   1207                                                     pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1208                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1209                                                             OMX_StateExecuting,NULL);
   1210                                                 }
   1211                                             }
   1212                                         } else {
   1213                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1214                                         }
   1215 
   1216                                         break;
   1217 
   1218                 case OMX_COMPONENT_GENERATE_STOP_DONE:
   1219                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
   1220                                         if (pThis->m_cb.EventHandler) {
   1221                                             if (p2 != VDEC_S_SUCCESS) {
   1222                                                 DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
   1223                                                 pThis->omx_report_error ();
   1224                                             } else {
   1225                                                 pThis->complete_pending_buffer_done_cbs();
   1226                                                 if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   1227                                                     DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
   1228                                                     // Send the callback now
   1229                                                     BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
   1230                                                     pThis->m_state = OMX_StateIdle;
   1231                                                     DEBUG_PRINT_LOW("Move to Idle State");
   1232                                                     pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
   1233                                                             OMX_EventCmdComplete,OMX_CommandStateSet,
   1234                                                             OMX_StateIdle,NULL);
   1235                                                 }
   1236                                             }
   1237                                         } else {
   1238                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1239                                         }
   1240 
   1241                                         break;
   1242 
   1243                 case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   1244                                         if (p2 == OMX_IndexParamPortDefinition) {
   1245                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexParamPortDefinition");
   1246                                             pThis->in_reconfig = true;
   1247 
   1248                                         }  else if (p2 == OMX_IndexConfigCommonOutputCrop) {
   1249                                             DEBUG_PRINT_HIGH("Rxd PORT_RECONFIG: OMX_IndexConfigCommonOutputCrop");
   1250 
   1251                                             /* Check if resolution is changed in smooth streaming mode */
   1252                                             if (pThis->m_smoothstreaming_mode &&
   1253                                                 (pThis->framesize.nWidth !=
   1254                                                     pThis->drv_ctx.video_resolution.frame_width) ||
   1255                                                 (pThis->framesize.nHeight !=
   1256                                                     pThis->drv_ctx.video_resolution.frame_height)) {
   1257 
   1258                                                 DEBUG_PRINT_HIGH("Resolution changed from: wxh = %dx%d to: wxh = %dx%d",
   1259                                                         pThis->framesize.nWidth,
   1260                                                         pThis->framesize.nHeight,
   1261                                                         pThis->drv_ctx.video_resolution.frame_width,
   1262                                                         pThis->drv_ctx.video_resolution.frame_height);
   1263 
   1264                                                 /* Update new resolution */
   1265                                                 pThis->framesize.nWidth =
   1266                                                        pThis->drv_ctx.video_resolution.frame_width;
   1267                                                 pThis->framesize.nHeight =
   1268                                                        pThis->drv_ctx.video_resolution.frame_height;
   1269 
   1270                                                 /* Update C2D with new resolution */
   1271                                                 if (!pThis->client_buffers.update_buffer_req()) {
   1272                                                     DEBUG_PRINT_ERROR("Setting C2D buffer requirements failed");
   1273                                                 }
   1274                                             }
   1275 
   1276                                             /* Update new crop information */
   1277                                             pThis->rectangle.nLeft = pThis->drv_ctx.frame_size.left;
   1278                                             pThis->rectangle.nTop = pThis->drv_ctx.frame_size.top;
   1279                                             pThis->rectangle.nWidth = pThis->drv_ctx.frame_size.right;
   1280                                             pThis->rectangle.nHeight = pThis->drv_ctx.frame_size.bottom;
   1281 
   1282                                             /* Validate the new crop information */
   1283                                             if (pThis->rectangle.nLeft + pThis->rectangle.nWidth >
   1284                                                 pThis->drv_ctx.video_resolution.frame_width) {
   1285 
   1286                                                 DEBUG_PRINT_HIGH("Crop L[%u] + R[%u] > W[%u]",
   1287                                                         pThis->rectangle.nLeft, pThis->rectangle.nWidth,
   1288                                                         pThis->drv_ctx.video_resolution.frame_width);
   1289                                                 pThis->rectangle.nLeft = 0;
   1290 
   1291                                                 if (pThis->rectangle.nWidth >
   1292                                                     pThis->drv_ctx.video_resolution.frame_width) {
   1293 
   1294                                                     DEBUG_PRINT_HIGH("Crop R[%u] > W[%u]",
   1295                                                             pThis->rectangle.nWidth,
   1296                                                             pThis->drv_ctx.video_resolution.frame_width);
   1297                                                     pThis->rectangle.nWidth =
   1298                                                         pThis->drv_ctx.video_resolution.frame_width;
   1299                                                 }
   1300                                             }
   1301                                             if (pThis->rectangle.nTop + pThis->rectangle.nHeight >
   1302                                                 pThis->drv_ctx.video_resolution.frame_height) {
   1303 
   1304                                                 DEBUG_PRINT_HIGH("Crop T[%u] + B[%u] > H[%u]",
   1305                                                     pThis->rectangle.nTop, pThis->rectangle.nHeight,
   1306                                                     pThis->drv_ctx.video_resolution.frame_height);
   1307                                                 pThis->rectangle.nTop = 0;
   1308 
   1309                                                 if (pThis->rectangle.nHeight >
   1310                                                     pThis->drv_ctx.video_resolution.frame_height) {
   1311 
   1312                                                     DEBUG_PRINT_HIGH("Crop B[%u] > H[%u]",
   1313                                                         pThis->rectangle.nHeight,
   1314                                                         pThis->drv_ctx.video_resolution.frame_height);
   1315                                                     pThis->rectangle.nHeight =
   1316                                                         pThis->drv_ctx.video_resolution.frame_height;
   1317                                                 }
   1318                                             }
   1319                                             DEBUG_PRINT_HIGH("Updated Crop Info: L: %u, T: %u, R: %u, B: %u",
   1320                                                     pThis->rectangle.nLeft, pThis->rectangle.nTop,
   1321                                                     pThis->rectangle.nWidth, pThis->rectangle.nHeight);
   1322                                         } else {
   1323                                             DEBUG_PRINT_ERROR("Rxd Invalid PORT_RECONFIG event (%lu)", p2);
   1324                                             break;
   1325                                         }
   1326                                         if (pThis->m_cb.EventHandler) {
   1327                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
   1328                                                     OMX_EventPortSettingsChanged, p1, p2, NULL );
   1329                                         } else {
   1330                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1331                                         }
   1332 
   1333                                         break;
   1334 
   1335                 case OMX_COMPONENT_GENERATE_EOS_DONE:
   1336                                         DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
   1337                                         if (pThis->m_cb.EventHandler) {
   1338                                             pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
   1339                                                     OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
   1340                                         } else {
   1341                                             DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
   1342                                         }
   1343                                         pThis->prev_ts = LLONG_MAX;
   1344                                         pThis->rst_prev_ts = true;
   1345                                         break;
   1346 
   1347                 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   1348                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
   1349                                         pThis->omx_report_error ();
   1350                                         break;
   1351 
   1352                 case OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING:
   1353                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING");
   1354                                         pThis->omx_report_unsupported_setting();
   1355                                         break;
   1356 
   1357                 case OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD:
   1358                                         DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD");
   1359                                         pThis->omx_report_hw_overload();
   1360                                         break;
   1361 
   1362                 default:
   1363                                         break;
   1364             }
   1365         }
   1366         pthread_mutex_lock(&pThis->m_lock);
   1367         qsize = pThis->m_cmd_q.m_size;
   1368         if (pThis->m_state != OMX_StatePause)
   1369             qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
   1370         pthread_mutex_unlock(&pThis->m_lock);
   1371     } while (qsize>0);
   1372 
   1373 }
   1374 
   1375 int omx_vdec::update_resolution(int width, int height, int stride, int scan_lines)
   1376 {
   1377     int format_changed = 0;
   1378     if ((height != (int)drv_ctx.video_resolution.frame_height) ||
   1379             (width != (int)drv_ctx.video_resolution.frame_width)) {
   1380         DEBUG_PRINT_HIGH("NOTE_CIF: W/H %d (%d), %d (%d)",
   1381                 width, drv_ctx.video_resolution.frame_width,
   1382                 height,drv_ctx.video_resolution.frame_height);
   1383         format_changed = 1;
   1384     }
   1385     drv_ctx.video_resolution.frame_height = height;
   1386     drv_ctx.video_resolution.frame_width = width;
   1387     drv_ctx.video_resolution.scan_lines = scan_lines;
   1388     drv_ctx.video_resolution.stride = stride;
   1389     if(!is_down_scalar_enabled) {
   1390     rectangle.nLeft = 0;
   1391     rectangle.nTop = 0;
   1392     rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   1393     rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   1394     }
   1395     return format_changed;
   1396 }
   1397 
   1398 OMX_ERRORTYPE omx_vdec::is_video_session_supported()
   1399 {
   1400     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",
   1401                 OMX_MAX_STRINGNAME_SIZE) &&
   1402             (m_profile == HIGH_PROFILE || m_profile == MAIN_PROFILE)) {
   1403         m_decoder_capability.max_width = 1280;
   1404         m_decoder_capability.max_height = 720;
   1405         DEBUG_PRINT_HIGH("Set max_width=1280 & max_height=720 for H264 HP/MP");
   1406     }
   1407 
   1408     if ((drv_ctx.video_resolution.frame_width *
   1409                 drv_ctx.video_resolution.frame_height >
   1410                 m_decoder_capability.max_width *
   1411                 m_decoder_capability.max_height) ||
   1412             (drv_ctx.video_resolution.frame_width*
   1413              drv_ctx.video_resolution.frame_height <
   1414              m_decoder_capability.min_width *
   1415              m_decoder_capability.min_height)) {
   1416         DEBUG_PRINT_ERROR(
   1417                 "Unsupported WxH = (%u)x(%u) supported range is min(%u)x(%u) - max(%u)x(%u)",
   1418                 drv_ctx.video_resolution.frame_width,
   1419                 drv_ctx.video_resolution.frame_height,
   1420                 m_decoder_capability.min_width,
   1421                 m_decoder_capability.min_height,
   1422                 m_decoder_capability.max_width,
   1423                 m_decoder_capability.max_height);
   1424         return OMX_ErrorUnsupportedSetting;
   1425     }
   1426     DEBUG_PRINT_HIGH("video session supported");
   1427     return OMX_ErrorNone;
   1428 }
   1429 
   1430 int omx_vdec::log_input_buffers(const char *buffer_addr, int buffer_len)
   1431 {
   1432     if (m_debug.in_buffer_log && !m_debug.infile) {
   1433         if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4", OMX_MAX_STRINGNAME_SIZE)) {
   1434            sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.m4v",
   1435                    m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1436         }
   1437         else if(!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2", OMX_MAX_STRINGNAME_SIZE)) {
   1438                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.mpg", m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this); }
   1439         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263", OMX_MAX_STRINGNAME_SIZE)) {
   1440                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.263",
   1441                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1442         }
   1443         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc", OMX_MAX_STRINGNAME_SIZE) ||
   1444                     !strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   1445                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.264",
   1446                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1447         }
   1448         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   1449                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.265",
   1450                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1451         }
   1452         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1", OMX_MAX_STRINGNAME_SIZE)) {
   1453                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
   1454                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1455         }
   1456         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv", OMX_MAX_STRINGNAME_SIZE)) {
   1457                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.vc1",
   1458                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1459         }
   1460         else if(!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   1461                 sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.ivf",
   1462                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1463         }
   1464         else {
   1465                sprintf(m_debug.infile_name, "%s/input_dec_%d_%d_%p.divx",
   1466                         m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1467         }
   1468         m_debug.infile = fopen (m_debug.infile_name, "ab");
   1469         if (!m_debug.infile) {
   1470             DEBUG_PRINT_HIGH("Failed to open input file: %s for logging", m_debug.infile_name);
   1471             m_debug.infile_name[0] = '\0';
   1472             return -1;
   1473         }
   1474         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   1475             struct ivf_file_header {
   1476                 OMX_U8 signature[4]; //='DKIF';
   1477                 OMX_U8 version         ; //= 0;
   1478                 OMX_U8 headersize      ; //= 32;
   1479                 OMX_U32 FourCC;
   1480                 OMX_U8 width;
   1481                 OMX_U8 height;
   1482                 OMX_U32 rate;
   1483                 OMX_U32 scale;
   1484                 OMX_U32 length;
   1485                 OMX_U8 unused[4];
   1486             } file_header;
   1487 
   1488             memset((void *)&file_header,0,sizeof(file_header));
   1489             file_header.signature[0] = 'D';
   1490             file_header.signature[1] = 'K';
   1491             file_header.signature[2] = 'I';
   1492             file_header.signature[3] = 'F';
   1493             file_header.version = 0;
   1494             file_header.headersize = 32;
   1495             file_header.FourCC = 0x30385056;
   1496             fwrite((const char *)&file_header,
   1497                     sizeof(file_header),1,m_debug.infile);
   1498          }
   1499     }
   1500     if (m_debug.infile && buffer_addr && buffer_len) {
   1501         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8", OMX_MAX_STRINGNAME_SIZE)) {
   1502             struct vp8_ivf_frame_header {
   1503                 OMX_U32 framesize;
   1504                 OMX_U32 timestamp_lo;
   1505                 OMX_U32 timestamp_hi;
   1506             } vp8_frame_header;
   1507             vp8_frame_header.framesize = buffer_len;
   1508             /* Currently FW doesn't use timestamp values */
   1509             vp8_frame_header.timestamp_lo = 0;
   1510             vp8_frame_header.timestamp_hi = 0;
   1511             fwrite((const char *)&vp8_frame_header,
   1512                     sizeof(vp8_frame_header),1,m_debug.infile);
   1513         }
   1514         fwrite(buffer_addr, buffer_len, 1, m_debug.infile);
   1515     }
   1516     return 0;
   1517 }
   1518 
   1519 int omx_vdec::log_output_buffers(OMX_BUFFERHEADERTYPE *buffer) {
   1520     if (m_debug.out_buffer_log && !m_debug.outfile && buffer->nFilledLen) {
   1521         sprintf(m_debug.outfile_name, "%s/output_%d_%d_%p.yuv",
   1522                 m_debug.log_loc, drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height, this);
   1523         m_debug.outfile = fopen (m_debug.outfile_name, "ab");
   1524         if (!m_debug.outfile) {
   1525             DEBUG_PRINT_HIGH("Failed to open output file: %s for logging", m_debug.log_loc);
   1526             m_debug.outfile_name[0] = '\0';
   1527             return -1;
   1528         }
   1529     }
   1530     if (m_debug.outfile && buffer && buffer->nFilledLen) {
   1531         int buf_index = buffer - m_out_mem_ptr;
   1532         int stride = drv_ctx.video_resolution.stride;
   1533         int scanlines = drv_ctx.video_resolution.scan_lines;
   1534         if (m_smoothstreaming_mode) {
   1535             stride = drv_ctx.video_resolution.frame_width;
   1536             scanlines = drv_ctx.video_resolution.frame_height;
   1537             stride = (stride + DEFAULT_WIDTH_ALIGNMENT - 1) & (~(DEFAULT_WIDTH_ALIGNMENT - 1));
   1538             scanlines = (scanlines + DEFAULT_HEIGHT_ALIGNMENT - 1) & (~(DEFAULT_HEIGHT_ALIGNMENT - 1));
   1539         }
   1540         char *temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr;
   1541         unsigned i;
   1542         DEBUG_PRINT_HIGH("Logging width/height(%u/%u) stride/scanlines(%u/%u)",
   1543             drv_ctx.video_resolution.frame_width,
   1544             drv_ctx.video_resolution.frame_height, stride, scanlines);
   1545         int bytes_written = 0;
   1546         for (i = 0; i < drv_ctx.video_resolution.frame_height; i++) {
   1547              bytes_written = fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1548              temp += stride;
   1549         }
   1550         temp = (char *)drv_ctx.ptr_outputbuffer[buf_index].bufferaddr + stride * scanlines;
   1551         int stride_c = stride;
   1552         for(i = 0; i < drv_ctx.video_resolution.frame_height/2; i++) {
   1553             bytes_written += fwrite(temp, drv_ctx.video_resolution.frame_width, 1, m_debug.outfile);
   1554             temp += stride_c;
   1555         }
   1556     }
   1557     return 0;
   1558 }
   1559 
   1560 /* ======================================================================
   1561    FUNCTION
   1562    omx_vdec::ComponentInit
   1563 
   1564    DESCRIPTION
   1565    Initialize the component.
   1566 
   1567    PARAMETERS
   1568    ctxt -- Context information related to the self.
   1569    id   -- Event identifier. This could be any of the following:
   1570    1. Command completion event
   1571    2. Buffer done callback event
   1572    3. Frame done callback event
   1573 
   1574    RETURN VALUE
   1575    None.
   1576 
   1577    ========================================================================== */
   1578 OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
   1579 {
   1580 
   1581     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   1582     struct v4l2_fmtdesc fdesc;
   1583     struct v4l2_format fmt;
   1584     struct v4l2_requestbuffers bufreq;
   1585     struct v4l2_control control;
   1586     struct v4l2_frmsizeenum frmsize;
   1587     unsigned int   alignment = 0,buffer_size = 0;
   1588     int fds[2];
   1589     int r,ret=0;
   1590     bool codec_ambiguous = false;
   1591     OMX_STRING device_name = (OMX_STRING)"/dev/video32";
   1592     char property_value[PROPERTY_VALUE_MAX] = {0};
   1593 
   1594 #ifdef _ANDROID_
   1595     char platform_name[PROPERTY_VALUE_MAX];
   1596     property_get("ro.board.platform", platform_name, "0");
   1597     if (!strncmp(platform_name, "msm8610", 7)) {
   1598         device_name = (OMX_STRING)"/dev/video/q6_dec";
   1599         is_q6_platform = true;
   1600         maxSmoothStreamingWidth = 1280;
   1601         maxSmoothStreamingHeight = 720;
   1602     }
   1603 #endif
   1604 
   1605 #ifdef _ANDROID_
   1606     /*
   1607      * turn off frame parsing for Android by default.
   1608      * Clients may configure OMX_QCOM_FramePacking_Arbitrary to enable this mode
   1609      */
   1610     arbitrary_bytes = false;
   1611     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   1612     if (atoi(property_value)) {
   1613         DEBUG_PRINT_HIGH("arbitrary_bytes mode enabled via property command");
   1614         arbitrary_bytes = true;
   1615     }
   1616 #endif
   1617 
   1618     if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",
   1619                 OMX_MAX_STRINGNAME_SIZE)) {
   1620         secure_mode = true;
   1621         arbitrary_bytes = false;
   1622         role = (OMX_STRING)"OMX.qcom.video.decoder.avc";
   1623     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",
   1624                 OMX_MAX_STRINGNAME_SIZE)) {
   1625         secure_mode = true;
   1626         arbitrary_bytes = false;
   1627         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg2";
   1628     } else if (!strncmp(role, "OMX.qcom.video.decoder.hevc.secure",
   1629                 OMX_MAX_STRINGNAME_SIZE)) {
   1630         secure_mode = true;
   1631         arbitrary_bytes = false;
   1632         role = (OMX_STRING)"OMX.qcom.video.decoder.hevc";
   1633     } else if (!strncmp(role, "OMX.qcom.video.decoder.vc1.secure",
   1634                 OMX_MAX_STRINGNAME_SIZE)) {
   1635         secure_mode = true;
   1636         arbitrary_bytes = false;
   1637         role = (OMX_STRING)"OMX.qcom.video.decoder.vc1";
   1638     } else if (!strncmp(role, "OMX.qcom.video.decoder.wmv.secure",
   1639                 OMX_MAX_STRINGNAME_SIZE)) {
   1640         secure_mode = true;
   1641         arbitrary_bytes = false;
   1642         role = (OMX_STRING)"OMX.qcom.video.decoder.wmv";
   1643     } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg4.secure",
   1644                 OMX_MAX_STRINGNAME_SIZE)) {
   1645         secure_mode = true;
   1646         arbitrary_bytes = false;
   1647         role = (OMX_STRING)"OMX.qcom.video.decoder.mpeg4";
   1648     }
   1649 
   1650     drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   1651 
   1652     DEBUG_PRINT_INFO("component_init: %s : fd=%d", role, drv_ctx.video_driver_fd);
   1653 
   1654     if (drv_ctx.video_driver_fd == 0) {
   1655         DEBUG_PRINT_ERROR("omx_vdec_msm8974 :: Got fd as 0 for msm_vidc_dec, Opening again");
   1656         drv_ctx.video_driver_fd = open(device_name, O_RDWR);
   1657         close(0);
   1658     }
   1659 
   1660     if (drv_ctx.video_driver_fd < 0) {
   1661         DEBUG_PRINT_ERROR("Omx_vdec::Comp Init Returning failure, errno %d", errno);
   1662         return OMX_ErrorInsufficientResources;
   1663     }
   1664     drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
   1665     drv_ctx.frame_rate.fps_denominator = 1;
   1666 
   1667     ret = subscribe_to_events(drv_ctx.video_driver_fd);
   1668     if (!ret) {
   1669         async_thread_created = true;
   1670         ret = pthread_create(&async_thread_id,0,async_message_thread,this);
   1671     }
   1672     if (ret) {
   1673         DEBUG_PRINT_ERROR("Failed to create async_message_thread");
   1674         async_thread_created = false;
   1675         return OMX_ErrorInsufficientResources;
   1676     }
   1677 
   1678 #ifdef OUTPUT_EXTRADATA_LOG
   1679     outputExtradataFile = fopen (output_extradata_filename, "ab");
   1680 #endif
   1681 
   1682     // Copy the role information which provides the decoder kind
   1683     strlcpy(drv_ctx.kind,role,128);
   1684 
   1685     if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
   1686                 OMX_MAX_STRINGNAME_SIZE)) {
   1687         strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
   1688                 OMX_MAX_STRINGNAME_SIZE);
   1689         drv_ctx.timestamp_adjust = true;
   1690         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
   1691         eCompressionFormat = OMX_VIDEO_CodingMPEG4;
   1692         output_capability=V4L2_PIX_FMT_MPEG4;
   1693         /*Initialize Start Code for MPEG4*/
   1694         codec_type_parse = CODEC_TYPE_MPEG4;
   1695         m_frame_parser.init_start_codes (codec_type_parse);
   1696     } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
   1697                 OMX_MAX_STRINGNAME_SIZE)) {
   1698         strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
   1699                 OMX_MAX_STRINGNAME_SIZE);
   1700         drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
   1701         output_capability = V4L2_PIX_FMT_MPEG2;
   1702         eCompressionFormat = OMX_VIDEO_CodingMPEG2;
   1703         /*Initialize Start Code for MPEG2*/
   1704         codec_type_parse = CODEC_TYPE_MPEG2;
   1705         m_frame_parser.init_start_codes (codec_type_parse);
   1706     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
   1707                 OMX_MAX_STRINGNAME_SIZE)) {
   1708         strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   1709         DEBUG_PRINT_LOW("H263 Decoder selected");
   1710         drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
   1711         eCompressionFormat = OMX_VIDEO_CodingH263;
   1712         output_capability = V4L2_PIX_FMT_H263;
   1713         codec_type_parse = CODEC_TYPE_H263;
   1714         m_frame_parser.init_start_codes (codec_type_parse);
   1715     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
   1716                 OMX_MAX_STRINGNAME_SIZE)) {
   1717         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1718         DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
   1719         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
   1720         output_capability = V4L2_PIX_FMT_DIVX_311;
   1721         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1722         codec_type_parse = CODEC_TYPE_DIVX;
   1723         m_frame_parser.init_start_codes (codec_type_parse);
   1724 
   1725         eRet = createDivxDrmContext();
   1726         if (eRet != OMX_ErrorNone) {
   1727             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1728             return eRet;
   1729         }
   1730     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
   1731                 OMX_MAX_STRINGNAME_SIZE)) {
   1732         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1733         DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
   1734         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
   1735         output_capability = V4L2_PIX_FMT_DIVX;
   1736         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1737         codec_type_parse = CODEC_TYPE_DIVX;
   1738         codec_ambiguous = true;
   1739         m_frame_parser.init_start_codes (codec_type_parse);
   1740 
   1741         eRet = createDivxDrmContext();
   1742         if (eRet != OMX_ErrorNone) {
   1743             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1744             return eRet;
   1745         }
   1746     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
   1747                 OMX_MAX_STRINGNAME_SIZE)) {
   1748         strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   1749         DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
   1750         drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
   1751         output_capability = V4L2_PIX_FMT_DIVX;
   1752         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
   1753         codec_type_parse = CODEC_TYPE_DIVX;
   1754         codec_ambiguous = true;
   1755         m_frame_parser.init_start_codes (codec_type_parse);
   1756 
   1757         eRet = createDivxDrmContext();
   1758         if (eRet != OMX_ErrorNone) {
   1759             DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
   1760             return eRet;
   1761         }
   1762 
   1763     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
   1764                 OMX_MAX_STRINGNAME_SIZE)) {
   1765         strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   1766         drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
   1767         output_capability=V4L2_PIX_FMT_H264;
   1768         eCompressionFormat = OMX_VIDEO_CodingAVC;
   1769         codec_type_parse = CODEC_TYPE_H264;
   1770         m_frame_parser.init_start_codes (codec_type_parse);
   1771         m_frame_parser.init_nal_length(nal_length);
   1772     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc",\
   1773                 OMX_MAX_STRINGNAME_SIZE)) {
   1774         strlcpy((char *)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   1775         drv_ctx.decoder_format = VDEC_CODECTYPE_MVC;
   1776         output_capability = V4L2_PIX_FMT_H264_MVC;
   1777         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC;
   1778         codec_type_parse = CODEC_TYPE_H264;
   1779         m_frame_parser.init_start_codes(codec_type_parse);
   1780         m_frame_parser.init_nal_length(nal_length);
   1781     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc",\
   1782                 OMX_MAX_STRINGNAME_SIZE)) {
   1783         strlcpy((char *)m_cRole, "video_decoder.hevc",OMX_MAX_STRINGNAME_SIZE);
   1784         drv_ctx.decoder_format = VDEC_CODECTYPE_HEVC;
   1785         output_capability = V4L2_PIX_FMT_HEVC;
   1786         eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingHevc;
   1787         codec_type_parse = CODEC_TYPE_HEVC;
   1788         m_frame_parser.init_start_codes(codec_type_parse);
   1789         m_frame_parser.init_nal_length(nal_length);
   1790     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
   1791                 OMX_MAX_STRINGNAME_SIZE)) {
   1792         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   1793         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
   1794         eCompressionFormat = OMX_VIDEO_CodingWMV;
   1795         codec_type_parse = CODEC_TYPE_VC1;
   1796         output_capability = V4L2_PIX_FMT_VC1_ANNEX_G;
   1797         m_frame_parser.init_start_codes (codec_type_parse);
   1798     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
   1799                 OMX_MAX_STRINGNAME_SIZE)) {
   1800         strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   1801         drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
   1802         eCompressionFormat = OMX_VIDEO_CodingWMV;
   1803         codec_type_parse = CODEC_TYPE_VC1;
   1804         output_capability = V4L2_PIX_FMT_VC1_ANNEX_L;
   1805         m_frame_parser.init_start_codes (codec_type_parse);
   1806     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",    \
   1807                 OMX_MAX_STRINGNAME_SIZE)) {
   1808         strlcpy((char *)m_cRole, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   1809         output_capability=V4L2_PIX_FMT_VP8;
   1810         eCompressionFormat = OMX_VIDEO_CodingVP8;
   1811         codec_type_parse = CODEC_TYPE_VP8;
   1812         arbitrary_bytes = false;
   1813 
   1814     } else {
   1815         DEBUG_PRINT_ERROR("ERROR:Unknown Component");
   1816         eRet = OMX_ErrorInvalidComponentName;
   1817     }
   1818     if (eRet == OMX_ErrorNone) {
   1819         OMX_COLOR_FORMATTYPE dest_color_format;
   1820         drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
   1821         if (eCompressionFormat == (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingMVC)
   1822             dest_color_format = (OMX_COLOR_FORMATTYPE)
   1823                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   1824         else
   1825             dest_color_format = (OMX_COLOR_FORMATTYPE)
   1826             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   1827         if (!client_buffers.set_color_format(dest_color_format)) {
   1828             DEBUG_PRINT_ERROR("Setting color format failed");
   1829             eRet = OMX_ErrorInsufficientResources;
   1830         }
   1831 
   1832         capture_capability= V4L2_PIX_FMT_NV12;
   1833 
   1834         struct v4l2_capability cap;
   1835         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_QUERYCAP, &cap);
   1836         if (ret) {
   1837             DEBUG_PRINT_ERROR("Failed to query capabilities");
   1838             /*TODO: How to handle this case */
   1839         } else {
   1840             DEBUG_PRINT_INFO("Capabilities: driver_name = %s, card = %s, bus_info = %s,"
   1841                     " version = %d, capabilities = %x", cap.driver, cap.card,
   1842                     cap.bus_info, cap.version, cap.capabilities);
   1843         }
   1844         ret=0;
   1845         fdesc.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1846         fdesc.index=0;
   1847         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1848             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   1849                     fdesc.pixelformat, fdesc.flags);
   1850             fdesc.index++;
   1851         }
   1852         fdesc.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1853         fdesc.index=0;
   1854         while (ioctl(drv_ctx.video_driver_fd, VIDIOC_ENUM_FMT, &fdesc) == 0) {
   1855 
   1856             DEBUG_PRINT_HIGH("fmt: description: %s, fmt: %x, flags = %x", fdesc.description,
   1857                     fdesc.pixelformat, fdesc.flags);
   1858             fdesc.index++;
   1859         }
   1860         update_resolution(320, 240, 320, 240);
   1861         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   1862         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1863         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1864         fmt.fmt.pix_mp.pixelformat = output_capability;
   1865         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1866         if (ret) {
   1867             /*TODO: How to handle this case */
   1868             DEBUG_PRINT_ERROR("Failed to set format on output port");
   1869             return OMX_ErrorInsufficientResources;
   1870         }
   1871         DEBUG_PRINT_HIGH("Set Format was successful");
   1872         if (codec_ambiguous) {
   1873             if (output_capability == V4L2_PIX_FMT_DIVX) {
   1874                 struct v4l2_control divx_ctrl;
   1875 
   1876                 if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_4) {
   1877                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_4;
   1878                 } else if (drv_ctx.decoder_format == VDEC_CODECTYPE_DIVX_5) {
   1879                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_5;
   1880                 } else {
   1881                     divx_ctrl.value = V4L2_MPEG_VIDC_VIDEO_DIVX_FORMAT_6;
   1882                 }
   1883 
   1884                 divx_ctrl.id = V4L2_CID_MPEG_VIDC_VIDEO_DIVX_FORMAT;
   1885                 ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &divx_ctrl);
   1886                 if (ret) {
   1887                     DEBUG_PRINT_ERROR("Failed to set divx version");
   1888                 }
   1889             } else {
   1890                 DEBUG_PRINT_ERROR("Codec should not be ambiguous");
   1891             }
   1892         }
   1893 
   1894         property_get("persist.vidc.dec.conceal_color", property_value, DEFAULT_CONCEAL_COLOR);
   1895         m_conceal_color= atoi(property_value);
   1896         DEBUG_PRINT_HIGH("trying to set 0x%u as conceal color\n", (unsigned int)m_conceal_color);
   1897         control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONCEAL_COLOR;
   1898         control.value = m_conceal_color;
   1899         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1900         if (ret) {
   1901             DEBUG_PRINT_ERROR("Failed to set conceal color %d\n", ret);
   1902         }
   1903 
   1904         //Get the hardware capabilities
   1905         memset((void *)&frmsize,0,sizeof(frmsize));
   1906         frmsize.index = 0;
   1907         frmsize.pixel_format = output_capability;
   1908         ret = ioctl(drv_ctx.video_driver_fd,
   1909                 VIDIOC_ENUM_FRAMESIZES, &frmsize);
   1910         if (ret || frmsize.type != V4L2_FRMSIZE_TYPE_STEPWISE) {
   1911             DEBUG_PRINT_ERROR("Failed to get framesizes");
   1912             return OMX_ErrorHardware;
   1913         }
   1914 
   1915         if (frmsize.type == V4L2_FRMSIZE_TYPE_STEPWISE) {
   1916             m_decoder_capability.min_width = frmsize.stepwise.min_width;
   1917             m_decoder_capability.max_width = frmsize.stepwise.max_width;
   1918             m_decoder_capability.min_height = frmsize.stepwise.min_height;
   1919             m_decoder_capability.max_height = frmsize.stepwise.max_height;
   1920         }
   1921 
   1922         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   1923         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   1924         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   1925         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   1926         fmt.fmt.pix_mp.pixelformat = capture_capability;
   1927         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   1928         if (ret) {
   1929             /*TODO: How to handle this case */
   1930             DEBUG_PRINT_ERROR("Failed to set format on capture port");
   1931         }
   1932         memset(&framesize, 0, sizeof(OMX_FRAMESIZETYPE));
   1933         framesize.nWidth = drv_ctx.video_resolution.frame_width;
   1934         framesize.nHeight = drv_ctx.video_resolution.frame_height;
   1935 
   1936         memset(&rectangle, 0, sizeof(OMX_CONFIG_RECTTYPE));
   1937         rectangle.nWidth = drv_ctx.video_resolution.frame_width;
   1938         rectangle.nHeight = drv_ctx.video_resolution.frame_height;
   1939 
   1940         DEBUG_PRINT_HIGH("Set Format was successful");
   1941         if (secure_mode) {
   1942             control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE;
   1943             control.value = 1;
   1944             DEBUG_PRINT_LOW("Omx_vdec:: calling to open secure device %d", ret);
   1945             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   1946             if (ret) {
   1947                 DEBUG_PRINT_ERROR("Omx_vdec:: Unable to open secure device %d", ret);
   1948                 return OMX_ErrorInsufficientResources;
   1949             }
   1950         }
   1951         if (output_capability == V4L2_PIX_FMT_H264_MVC) {
   1952             control.id = V4L2_CID_MPEG_VIDC_VIDEO_MVC_BUFFER_LAYOUT;
   1953             control.value = V4L2_MPEG_VIDC_VIDEO_MVC_TOP_BOTTOM;
   1954             ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   1955             if (ret) {
   1956                 DEBUG_PRINT_ERROR("Failed to set MVC buffer layout");
   1957                 return OMX_ErrorInsufficientResources;
   1958             }
   1959         }
   1960 
   1961         /*Get the Buffer requirements for input and output ports*/
   1962         drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   1963         drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   1964         if (secure_mode) {
   1965             drv_ctx.op_buf.alignment=SZ_1M;
   1966             drv_ctx.ip_buf.alignment=SZ_1M;
   1967         } else {
   1968             drv_ctx.op_buf.alignment=SZ_4K;
   1969             drv_ctx.ip_buf.alignment=SZ_4K;
   1970         }
   1971         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   1972         drv_ctx.extradata = 0;
   1973         drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
   1974         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   1975         control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   1976         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   1977         drv_ctx.idr_only_decoding = 0;
   1978 
   1979         property_get("vidc.debug.turbo", property_value, "0");
   1980         if (atoi(property_value)) {
   1981             DEBUG_PRINT_HIGH("Turbo mode debug property enabled");
   1982             control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   1983             control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   1984             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   1985                 DEBUG_PRINT_ERROR("Failed to set turbo mode");
   1986             }
   1987         }
   1988 
   1989         m_state = OMX_StateLoaded;
   1990 #ifdef DEFAULT_EXTRADATA
   1991         if (strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",
   1992                 OMX_MAX_STRINGNAME_SIZE)
   1993                 && (eRet == OMX_ErrorNone))
   1994                 enable_extradata(DEFAULT_EXTRADATA, true, true);
   1995 #endif
   1996         eRet=get_buffer_req(&drv_ctx.ip_buf);
   1997         DEBUG_PRINT_HIGH("Input Buffer Size =%u",(unsigned int)drv_ctx.ip_buf.buffer_size);
   1998         get_buffer_req(&drv_ctx.op_buf);
   1999         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2000                 drv_ctx.decoder_format == VDEC_CODECTYPE_HEVC ||
   2001                 drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2002                     h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size;
   2003                     h264_scratch.pBuffer = (OMX_U8 *)malloc (drv_ctx.ip_buf.buffer_size);
   2004                     h264_scratch.nFilledLen = 0;
   2005                     h264_scratch.nOffset = 0;
   2006 
   2007                     if (h264_scratch.pBuffer == NULL) {
   2008                         DEBUG_PRINT_ERROR("h264_scratch.pBuffer Allocation failed ");
   2009                         return OMX_ErrorInsufficientResources;
   2010                     }
   2011         }
   2012         if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264 ||
   2013             drv_ctx.decoder_format == VDEC_CODECTYPE_MVC) {
   2014             if (m_frame_parser.mutils == NULL) {
   2015                 m_frame_parser.mutils = new H264_Utils();
   2016                 if (m_frame_parser.mutils == NULL) {
   2017                     DEBUG_PRINT_ERROR("parser utils Allocation failed ");
   2018                     eRet = OMX_ErrorInsufficientResources;
   2019                 } else {
   2020                     m_frame_parser.mutils->initialize_frame_checking_environment();
   2021                     m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
   2022                 }
   2023             }
   2024 
   2025             h264_parser = new h264_stream_parser();
   2026             if (!h264_parser) {
   2027                 DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
   2028                 eRet = OMX_ErrorInsufficientResources;
   2029             }
   2030         }
   2031 
   2032         if (pipe(fds)) {
   2033             DEBUG_PRINT_ERROR("pipe creation failed");
   2034             eRet = OMX_ErrorInsufficientResources;
   2035         } else {
   2036             int temp1[2];
   2037             if (fds[0] == 0 || fds[1] == 0) {
   2038                 if (pipe (temp1)) {
   2039                     DEBUG_PRINT_ERROR("pipe creation failed");
   2040                     return OMX_ErrorInsufficientResources;
   2041                 }
   2042                 //close (fds[0]);
   2043                 //close (fds[1]);
   2044                 fds[0] = temp1 [0];
   2045                 fds[1] = temp1 [1];
   2046             }
   2047             m_pipe_in = fds[0];
   2048             m_pipe_out = fds[1];
   2049             msg_thread_created = true;
   2050             r = pthread_create(&msg_thread_id,0,message_thread,this);
   2051 
   2052             if (r < 0) {
   2053                 DEBUG_PRINT_ERROR("component_init(): message_thread creation failed");
   2054                 msg_thread_created = false;
   2055                 eRet = OMX_ErrorInsufficientResources;
   2056             }
   2057         }
   2058     }
   2059 
   2060     if (eRet != OMX_ErrorNone) {
   2061         DEBUG_PRINT_ERROR("Component Init Failed");
   2062     } else {
   2063         DEBUG_PRINT_INFO("omx_vdec::component_init() success : fd=%d",
   2064                 drv_ctx.video_driver_fd);
   2065     }
   2066     //memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
   2067     control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   2068     control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   2069 
   2070     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   2071         DEBUG_PRINT_ERROR("Failed to set Default Priority");
   2072         eRet = OMX_ErrorUnsupportedSetting;
   2073     }
   2074     return eRet;
   2075 }
   2076 
   2077 /* ======================================================================
   2078    FUNCTION
   2079    omx_vdec::GetComponentVersion
   2080 
   2081    DESCRIPTION
   2082    Returns the component version.
   2083 
   2084    PARAMETERS
   2085    TBD.
   2086 
   2087    RETURN VALUE
   2088    OMX_ErrorNone.
   2089 
   2090    ========================================================================== */
   2091 OMX_ERRORTYPE  omx_vdec::get_component_version
   2092 (
   2093  OMX_IN OMX_HANDLETYPE hComp,
   2094  OMX_OUT OMX_STRING componentName,
   2095  OMX_OUT OMX_VERSIONTYPE* componentVersion,
   2096  OMX_OUT OMX_VERSIONTYPE* specVersion,
   2097  OMX_OUT OMX_UUIDTYPE* componentUUID
   2098  )
   2099 {
   2100     (void) hComp;
   2101     (void) componentName;
   2102     (void) componentVersion;
   2103     (void) componentUUID;
   2104     if (m_state == OMX_StateInvalid) {
   2105         DEBUG_PRINT_ERROR("Get Comp Version in Invalid State");
   2106         return OMX_ErrorInvalidState;
   2107     }
   2108     /* TBD -- Return the proper version */
   2109     if (specVersion) {
   2110         specVersion->nVersion = OMX_SPEC_VERSION;
   2111     }
   2112     return OMX_ErrorNone;
   2113 }
   2114 /* ======================================================================
   2115    FUNCTION
   2116    omx_vdec::SendCommand
   2117 
   2118    DESCRIPTION
   2119    Returns zero if all the buffers released..
   2120 
   2121    PARAMETERS
   2122    None.
   2123 
   2124    RETURN VALUE
   2125    true/false
   2126 
   2127    ========================================================================== */
   2128 OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
   2129         OMX_IN OMX_COMMANDTYPE cmd,
   2130         OMX_IN OMX_U32 param1,
   2131         OMX_IN OMX_PTR cmdData
   2132         )
   2133 {
   2134     (void) hComp;
   2135     (void) cmdData;
   2136     DEBUG_PRINT_LOW("send_command: Recieved a Command from Client");
   2137     if (m_state == OMX_StateInvalid) {
   2138         DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State");
   2139         return OMX_ErrorInvalidState;
   2140     }
   2141     if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
   2142             && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
   2143         DEBUG_PRINT_ERROR("send_command(): ERROR OMX_CommandFlush "
   2144                 "to invalid port: %u", (unsigned int)param1);
   2145         return OMX_ErrorBadPortIndex;
   2146     }
   2147 
   2148     post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
   2149     sem_wait(&m_cmd_lock);
   2150     DEBUG_PRINT_LOW("send_command: Command Processed");
   2151     return OMX_ErrorNone;
   2152 }
   2153 
   2154 /* ======================================================================
   2155    FUNCTION
   2156    omx_vdec::SendCommand
   2157 
   2158    DESCRIPTION
   2159    Returns zero if all the buffers released..
   2160 
   2161    PARAMETERS
   2162    None.
   2163 
   2164    RETURN VALUE
   2165    true/false
   2166 
   2167    ========================================================================== */
   2168 OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
   2169         OMX_IN OMX_COMMANDTYPE cmd,
   2170         OMX_IN OMX_U32 param1,
   2171         OMX_IN OMX_PTR cmdData
   2172         )
   2173 {
   2174     (void) hComp;
   2175     (void) cmdData;
   2176     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2177     OMX_STATETYPE eState = (OMX_STATETYPE) param1;
   2178     int bFlag = 1,sem_posted = 0,ret=0;
   2179 
   2180     DEBUG_PRINT_LOW("send_command_proxy(): cmd = %d", cmd);
   2181     DEBUG_PRINT_HIGH("send_command_proxy(): Current State %d, Expected State %d",
   2182             m_state, eState);
   2183 
   2184     if (cmd == OMX_CommandStateSet) {
   2185         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
   2186         DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
   2187         /***************************/
   2188         /* Current State is Loaded */
   2189         /***************************/
   2190         if (m_state == OMX_StateLoaded) {
   2191             if (eState == OMX_StateIdle) {
   2192                 //if all buffers are allocated or all ports disabled
   2193                 if (allocate_done() ||
   2194                         (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
   2195                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
   2196                 } else {
   2197                     DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
   2198                     BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
   2199                     // Skip the event notification
   2200                     bFlag = 0;
   2201                 }
   2202             }
   2203             /* Requesting transition from Loaded to Loaded */
   2204             else if (eState == OMX_StateLoaded) {
   2205                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Loaded");
   2206                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2207                         OMX_COMPONENT_GENERATE_EVENT);
   2208                 eRet = OMX_ErrorSameState;
   2209             }
   2210             /* Requesting transition from Loaded to WaitForResources */
   2211             else if (eState == OMX_StateWaitForResources) {
   2212                 /* Since error is None , we will post an event
   2213                    at the end of this function definition */
   2214                 DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
   2215             }
   2216             /* Requesting transition from Loaded to Executing */
   2217             else if (eState == OMX_StateExecuting) {
   2218                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing");
   2219                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2220                         OMX_COMPONENT_GENERATE_EVENT);
   2221                 eRet = OMX_ErrorIncorrectStateTransition;
   2222             }
   2223             /* Requesting transition from Loaded to Pause */
   2224             else if (eState == OMX_StatePause) {
   2225                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause");
   2226                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2227                         OMX_COMPONENT_GENERATE_EVENT);
   2228                 eRet = OMX_ErrorIncorrectStateTransition;
   2229             }
   2230             /* Requesting transition from Loaded to Invalid */
   2231             else if (eState == OMX_StateInvalid) {
   2232                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid");
   2233                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2234                 eRet = OMX_ErrorInvalidState;
   2235             } else {
   2236                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)",\
   2237                         eState);
   2238                 eRet = OMX_ErrorBadParameter;
   2239             }
   2240         }
   2241 
   2242         /***************************/
   2243         /* Current State is IDLE */
   2244         /***************************/
   2245         else if (m_state == OMX_StateIdle) {
   2246             if (eState == OMX_StateLoaded) {
   2247                 if (release_done()) {
   2248                     /*
   2249                        Since error is None , we will post an event at the end
   2250                        of this function definition
   2251                      */
   2252                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded");
   2253                 } else {
   2254                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Loaded-Pending");
   2255                     BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
   2256                     // Skip the event notification
   2257                     bFlag = 0;
   2258                 }
   2259             }
   2260             /* Requesting transition from Idle to Executing */
   2261             else if (eState == OMX_StateExecuting) {
   2262                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2263                 //BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
   2264                 bFlag = 1;
   2265                 DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   2266                 m_state=OMX_StateExecuting;
   2267                 DEBUG_PRINT_HIGH("Stream On CAPTURE Was successful");
   2268             }
   2269             /* Requesting transition from Idle to Idle */
   2270             else if (eState == OMX_StateIdle) {
   2271                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle");
   2272                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2273                         OMX_COMPONENT_GENERATE_EVENT);
   2274                 eRet = OMX_ErrorSameState;
   2275             }
   2276             /* Requesting transition from Idle to WaitForResources */
   2277             else if (eState == OMX_StateWaitForResources) {
   2278                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources");
   2279                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2280                         OMX_COMPONENT_GENERATE_EVENT);
   2281                 eRet = OMX_ErrorIncorrectStateTransition;
   2282             }
   2283             /* Requesting transition from Idle to Pause */
   2284             else if (eState == OMX_StatePause) {
   2285                 /*To pause the Video core we need to start the driver*/
   2286                 if (/*ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
   2287                       NULL) < */0) {
   2288                     DEBUG_PRINT_ERROR("VDEC_IOCTL_CMD_START FAILED");
   2289                     omx_report_error ();
   2290                     eRet = OMX_ErrorHardware;
   2291                 } else {
   2292                     BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
   2293                     DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Pause");
   2294                     bFlag = 0;
   2295                 }
   2296             }
   2297             /* Requesting transition from Idle to Invalid */
   2298             else if (eState == OMX_StateInvalid) {
   2299                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid");
   2300                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2301                 eRet = OMX_ErrorInvalidState;
   2302             } else {
   2303                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled",eState);
   2304                 eRet = OMX_ErrorBadParameter;
   2305             }
   2306         }
   2307 
   2308         /******************************/
   2309         /* Current State is Executing */
   2310         /******************************/
   2311         else if (m_state == OMX_StateExecuting) {
   2312             DEBUG_PRINT_LOW("Command Recieved in OMX_StateExecuting");
   2313             /* Requesting transition from Executing to Idle */
   2314             if (eState == OMX_StateIdle) {
   2315                 /* Since error is None , we will post an event
   2316                    at the end of this function definition
   2317                  */
   2318                 DEBUG_PRINT_LOW("send_command_proxy(): Executing --> Idle");
   2319                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2320                 if (!sem_posted) {
   2321                     sem_posted = 1;
   2322                     sem_post (&m_cmd_lock);
   2323                     execute_omx_flush(OMX_ALL);
   2324                 }
   2325                 bFlag = 0;
   2326             }
   2327             /* Requesting transition from Executing to Paused */
   2328             else if (eState == OMX_StatePause) {
   2329                 DEBUG_PRINT_LOW("PAUSE Command Issued");
   2330                 m_state = OMX_StatePause;
   2331                 bFlag = 1;
   2332             }
   2333             /* Requesting transition from Executing to Loaded */
   2334             else if (eState == OMX_StateLoaded) {
   2335                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Loaded");
   2336                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2337                         OMX_COMPONENT_GENERATE_EVENT);
   2338                 eRet = OMX_ErrorIncorrectStateTransition;
   2339             }
   2340             /* Requesting transition from Executing to WaitForResources */
   2341             else if (eState == OMX_StateWaitForResources) {
   2342                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> WaitForResources");
   2343                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2344                         OMX_COMPONENT_GENERATE_EVENT);
   2345                 eRet = OMX_ErrorIncorrectStateTransition;
   2346             }
   2347             /* Requesting transition from Executing to Executing */
   2348             else if (eState == OMX_StateExecuting) {
   2349                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Executing");
   2350                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2351                         OMX_COMPONENT_GENERATE_EVENT);
   2352                 eRet = OMX_ErrorSameState;
   2353             }
   2354             /* Requesting transition from Executing to Invalid */
   2355             else if (eState == OMX_StateInvalid) {
   2356                 DEBUG_PRINT_ERROR("send_command_proxy(): Executing --> Invalid");
   2357                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2358                 eRet = OMX_ErrorInvalidState;
   2359             } else {
   2360                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled",eState);
   2361                 eRet = OMX_ErrorBadParameter;
   2362             }
   2363         }
   2364         /***************************/
   2365         /* Current State is Pause  */
   2366         /***************************/
   2367         else if (m_state == OMX_StatePause) {
   2368             /* Requesting transition from Pause to Executing */
   2369             if (eState == OMX_StateExecuting) {
   2370                 DEBUG_PRINT_LOW("Pause --> Executing");
   2371                 m_state = OMX_StateExecuting;
   2372                 bFlag = 1;
   2373             }
   2374             /* Requesting transition from Pause to Idle */
   2375             else if (eState == OMX_StateIdle) {
   2376                 /* Since error is None , we will post an event
   2377                    at the end of this function definition */
   2378                 DEBUG_PRINT_LOW("Pause --> Idle");
   2379                 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
   2380                 if (!sem_posted) {
   2381                     sem_posted = 1;
   2382                     sem_post (&m_cmd_lock);
   2383                     execute_omx_flush(OMX_ALL);
   2384                 }
   2385                 bFlag = 0;
   2386             }
   2387             /* Requesting transition from Pause to loaded */
   2388             else if (eState == OMX_StateLoaded) {
   2389                 DEBUG_PRINT_ERROR("Pause --> loaded");
   2390                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2391                         OMX_COMPONENT_GENERATE_EVENT);
   2392                 eRet = OMX_ErrorIncorrectStateTransition;
   2393             }
   2394             /* Requesting transition from Pause to WaitForResources */
   2395             else if (eState == OMX_StateWaitForResources) {
   2396                 DEBUG_PRINT_ERROR("Pause --> WaitForResources");
   2397                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2398                         OMX_COMPONENT_GENERATE_EVENT);
   2399                 eRet = OMX_ErrorIncorrectStateTransition;
   2400             }
   2401             /* Requesting transition from Pause to Pause */
   2402             else if (eState == OMX_StatePause) {
   2403                 DEBUG_PRINT_ERROR("Pause --> Pause");
   2404                 post_event(OMX_EventError,OMX_ErrorSameState,\
   2405                         OMX_COMPONENT_GENERATE_EVENT);
   2406                 eRet = OMX_ErrorSameState;
   2407             }
   2408             /* Requesting transition from Pause to Invalid */
   2409             else if (eState == OMX_StateInvalid) {
   2410                 DEBUG_PRINT_ERROR("Pause --> Invalid");
   2411                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2412                 eRet = OMX_ErrorInvalidState;
   2413             } else {
   2414                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled",eState);
   2415                 eRet = OMX_ErrorBadParameter;
   2416             }
   2417         }
   2418         /***************************/
   2419         /* Current State is WaitForResources  */
   2420         /***************************/
   2421         else if (m_state == OMX_StateWaitForResources) {
   2422             /* Requesting transition from WaitForResources to Loaded */
   2423             if (eState == OMX_StateLoaded) {
   2424                 /* Since error is None , we will post an event
   2425                    at the end of this function definition */
   2426                 DEBUG_PRINT_LOW("send_command_proxy(): WaitForResources-->Loaded");
   2427             }
   2428             /* Requesting transition from WaitForResources to WaitForResources */
   2429             else if (eState == OMX_StateWaitForResources) {
   2430                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources");
   2431                 post_event(OMX_EventError,OMX_ErrorSameState,
   2432                         OMX_COMPONENT_GENERATE_EVENT);
   2433                 eRet = OMX_ErrorSameState;
   2434             }
   2435             /* Requesting transition from WaitForResources to Executing */
   2436             else if (eState == OMX_StateExecuting) {
   2437                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing");
   2438                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2439                         OMX_COMPONENT_GENERATE_EVENT);
   2440                 eRet = OMX_ErrorIncorrectStateTransition;
   2441             }
   2442             /* Requesting transition from WaitForResources to Pause */
   2443             else if (eState == OMX_StatePause) {
   2444                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause");
   2445                 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
   2446                         OMX_COMPONENT_GENERATE_EVENT);
   2447                 eRet = OMX_ErrorIncorrectStateTransition;
   2448             }
   2449             /* Requesting transition from WaitForResources to Invalid */
   2450             else if (eState == OMX_StateInvalid) {
   2451                 DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid");
   2452                 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
   2453                 eRet = OMX_ErrorInvalidState;
   2454             }
   2455             /* Requesting transition from WaitForResources to Loaded -
   2456                is NOT tested by Khronos TS */
   2457 
   2458         } else {
   2459             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)",m_state,eState);
   2460             eRet = OMX_ErrorBadParameter;
   2461         }
   2462     }
   2463     /********************************/
   2464     /* Current State is Invalid */
   2465     /*******************************/
   2466     else if (m_state == OMX_StateInvalid) {
   2467         /* State Transition from Inavlid to any state */
   2468         if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
   2469                     || OMX_StateIdle || OMX_StateExecuting
   2470                     || OMX_StatePause || OMX_StateInvalid)) {
   2471             DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded");
   2472             post_event(OMX_EventError,OMX_ErrorInvalidState,\
   2473                     OMX_COMPONENT_GENERATE_EVENT);
   2474             eRet = OMX_ErrorInvalidState;
   2475         }
   2476     } else if (cmd == OMX_CommandFlush) {
   2477         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued"
   2478                 "with param1: %u", (unsigned int)param1);
   2479 #ifdef _MSM8974_
   2480         send_codec_config();
   2481 #endif
   2482         if (cmd == OMX_CommandFlush && (param1 == OMX_CORE_INPUT_PORT_INDEX ||
   2483                     param1 == OMX_ALL)) {
   2484             if (android_atomic_add(0, &m_queued_codec_config_count) > 0) {
   2485                struct timespec ts;
   2486 
   2487                clock_gettime(CLOCK_REALTIME, &ts);
   2488                ts.tv_sec += 2;
   2489                DEBUG_PRINT_LOW("waiting for %d EBDs of CODEC CONFIG buffers ",
   2490                        m_queued_codec_config_count);
   2491                BITMASK_SET(&m_flags, OMX_COMPONENT_FLUSH_DEFERRED);
   2492                if (sem_timedwait(&m_safe_flush, &ts)) {
   2493                    DEBUG_PRINT_ERROR("Failed to wait for EBDs of CODEC CONFIG buffers");
   2494                }
   2495                BITMASK_CLEAR (&m_flags,OMX_COMPONENT_FLUSH_DEFERRED);
   2496             }
   2497         }
   2498 
   2499         if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2500             BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
   2501         }
   2502         if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
   2503             BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
   2504         }
   2505         if (!sem_posted) {
   2506             sem_posted = 1;
   2507             DEBUG_PRINT_LOW("Set the Semaphore");
   2508             sem_post (&m_cmd_lock);
   2509             execute_omx_flush(param1);
   2510         }
   2511         bFlag = 0;
   2512     } else if ( cmd == OMX_CommandPortEnable) {
   2513         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued"
   2514                 "with param1: %u", (unsigned int)param1);
   2515         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2516             m_inp_bEnabled = OMX_TRUE;
   2517 
   2518             if ( (m_state == OMX_StateLoaded &&
   2519                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2520                     || allocate_input_done()) {
   2521                 post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
   2522                         OMX_COMPONENT_GENERATE_EVENT);
   2523             } else {
   2524                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   2525                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
   2526                 // Skip the event notification
   2527                 bFlag = 0;
   2528             }
   2529         }
   2530         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   2531             DEBUG_PRINT_LOW("Enable output Port command recieved");
   2532             m_out_bEnabled = OMX_TRUE;
   2533 
   2534             if ( (m_state == OMX_StateLoaded &&
   2535                         !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
   2536                     || (allocate_output_done())) {
   2537                 post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
   2538                         OMX_COMPONENT_GENERATE_EVENT);
   2539 
   2540             } else {
   2541                 DEBUG_PRINT_LOW("send_command_proxy(): Disabled-->Enabled Pending");
   2542                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   2543                 // Skip the event notification
   2544                 bFlag = 0;
   2545             }
   2546         }
   2547     } else if (cmd == OMX_CommandPortDisable) {
   2548         DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued"
   2549                 "with param1: %u", (unsigned int)param1);
   2550         if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
   2551             codec_config_flag = false;
   2552             m_inp_bEnabled = OMX_FALSE;
   2553             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2554                     && release_input_done()) {
   2555                 post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
   2556                         OMX_COMPONENT_GENERATE_EVENT);
   2557             } else {
   2558                 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
   2559                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   2560                     if (!sem_posted) {
   2561                         sem_posted = 1;
   2562                         sem_post (&m_cmd_lock);
   2563                     }
   2564                     execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
   2565                 }
   2566 
   2567                 // Skip the event notification
   2568                 bFlag = 0;
   2569             }
   2570         }
   2571         if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
   2572             m_out_bEnabled = OMX_FALSE;
   2573             DEBUG_PRINT_LOW("Disable output Port command recieved");
   2574             if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
   2575                     && release_output_done()) {
   2576                 post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
   2577                         OMX_COMPONENT_GENERATE_EVENT);
   2578             } else {
   2579                 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   2580                 if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
   2581                     if (!sem_posted) {
   2582                         sem_posted = 1;
   2583                         sem_post (&m_cmd_lock);
   2584                     }
   2585                     BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
   2586                     execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
   2587                 }
   2588                 // Skip the event notification
   2589                 bFlag = 0;
   2590 
   2591             }
   2592         }
   2593     } else {
   2594         DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)",cmd);
   2595         eRet = OMX_ErrorNotImplemented;
   2596     }
   2597     if (eRet == OMX_ErrorNone && bFlag) {
   2598         post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
   2599     }
   2600     if (!sem_posted) {
   2601         sem_post(&m_cmd_lock);
   2602     }
   2603 
   2604     return eRet;
   2605 }
   2606 
   2607 /* ======================================================================
   2608    FUNCTION
   2609    omx_vdec::ExecuteOmxFlush
   2610 
   2611    DESCRIPTION
   2612    Executes the OMX flush.
   2613 
   2614    PARAMETERS
   2615    flushtype - input flush(1)/output flush(0)/ both.
   2616 
   2617    RETURN VALUE
   2618    true/false
   2619 
   2620    ========================================================================== */
   2621 bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
   2622 {
   2623     bool bRet = false;
   2624     struct v4l2_plane plane;
   2625     struct v4l2_buffer v4l2_buf;
   2626     struct v4l2_decoder_cmd dec;
   2627     DEBUG_PRINT_LOW("in %s, flushing %u", __func__, (unsigned int)flushType);
   2628     memset((void *)&v4l2_buf,0,sizeof(v4l2_buf));
   2629     dec.cmd = V4L2_DEC_QCOM_CMD_FLUSH;
   2630 
   2631     DEBUG_PRINT_HIGH("in %s: reconfig? %d", __func__, in_reconfig);
   2632 
   2633     if (in_reconfig && flushType == OMX_CORE_OUTPUT_PORT_INDEX) {
   2634         output_flush_progress = true;
   2635         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   2636     } else {
   2637         /* XXX: The driver/hardware does not support flushing of individual ports
   2638          * in all states. So we pretty much need to flush both ports internally,
   2639          * but client should only get the FLUSH_(INPUT|OUTPUT)_DONE for the one it
   2640          * requested.  Since OMX_COMPONENT_(OUTPUT|INPUT)_FLUSH_PENDING isn't set,
   2641          * we automatically omit sending the FLUSH done for the "opposite" port. */
   2642         input_flush_progress = true;
   2643         output_flush_progress = true;
   2644         dec.flags = V4L2_DEC_QCOM_CMD_FLUSH_OUTPUT | V4L2_DEC_QCOM_CMD_FLUSH_CAPTURE;
   2645     }
   2646 
   2647     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_DECODER_CMD, &dec)) {
   2648         DEBUG_PRINT_ERROR("Flush Port (%u) Failed ", (unsigned int)flushType);
   2649         bRet = false;
   2650     }
   2651 
   2652     return bRet;
   2653 }
   2654 /*=========================================================================
   2655 FUNCTION : execute_output_flush
   2656 
   2657 DESCRIPTION
   2658 Executes the OMX flush at OUTPUT PORT.
   2659 
   2660 PARAMETERS
   2661 None.
   2662 
   2663 RETURN VALUE
   2664 true/false
   2665 ==========================================================================*/
   2666 bool omx_vdec::execute_output_flush()
   2667 {
   2668     unsigned long p1 = 0; // Parameter - 1
   2669     unsigned long p2 = 0; // Parameter - 2
   2670     unsigned long ident = 0;
   2671     bool bRet = true;
   2672 
   2673     /*Generate FBD for all Buffers in the FTBq*/
   2674     pthread_mutex_lock(&m_lock);
   2675     DEBUG_PRINT_LOW("Initiate Output Flush");
   2676 
   2677     //reset last render TS
   2678     if(m_last_rendered_TS > 0) {
   2679         m_last_rendered_TS = 0;
   2680     }
   2681 
   2682     while (m_ftb_q.m_size) {
   2683         DEBUG_PRINT_LOW("Buffer queue size %lu pending buf cnt %d",
   2684                 m_ftb_q.m_size,pending_output_buffers);
   2685         m_ftb_q.pop_entry(&p1,&p2,&ident);
   2686         DEBUG_PRINT_LOW("ID(%lx) P1(%lx) P2(%lx)", ident, p1, p2);
   2687         if (ident == m_fill_output_msg ) {
   2688             m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)(intptr_t)p2);
   2689         } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
   2690             fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)(intptr_t)p1);
   2691         }
   2692     }
   2693     pthread_mutex_unlock(&m_lock);
   2694     output_flush_progress = false;
   2695 
   2696     if (arbitrary_bytes) {
   2697         prev_ts = LLONG_MAX;
   2698         rst_prev_ts = true;
   2699     }
   2700     DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
   2701     return bRet;
   2702 }
   2703 /*=========================================================================
   2704 FUNCTION : execute_input_flush
   2705 
   2706 DESCRIPTION
   2707 Executes the OMX flush at INPUT PORT.
   2708 
   2709 PARAMETERS
   2710 None.
   2711 
   2712 RETURN VALUE
   2713 true/false
   2714 ==========================================================================*/
   2715 bool omx_vdec::execute_input_flush()
   2716 {
   2717     unsigned       i =0;
   2718     unsigned long p1 = 0; // Parameter - 1
   2719     unsigned long p2 = 0; // Parameter - 2
   2720     unsigned long ident = 0;
   2721     bool bRet = true;
   2722 
   2723     /*Generate EBD for all Buffers in the ETBq*/
   2724     DEBUG_PRINT_LOW("Initiate Input Flush");
   2725 
   2726     pthread_mutex_lock(&m_lock);
   2727     DEBUG_PRINT_LOW("Check if the Queue is empty");
   2728     while (m_etb_q.m_size) {
   2729         m_etb_q.pop_entry(&p1,&p2,&ident);
   2730 
   2731         if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   2732             DEBUG_PRINT_LOW("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   2733             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   2734         } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   2735             pending_input_buffers++;
   2736             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   2737                     (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   2738             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   2739         } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   2740             DEBUG_PRINT_LOW("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   2741                     (OMX_BUFFERHEADERTYPE *)p1);
   2742             empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   2743         }
   2744     }
   2745     time_stamp_dts.flush_timestamp();
   2746     /*Check if Heap Buffers are to be flushed*/
   2747     if (arbitrary_bytes && !(codec_config_flag)) {
   2748         DEBUG_PRINT_LOW("Reset all the variables before flusing");
   2749         h264_scratch.nFilledLen = 0;
   2750         nal_count = 0;
   2751         look_ahead_nal = false;
   2752         frame_count = 0;
   2753         h264_last_au_ts = LLONG_MAX;
   2754         h264_last_au_flags = 0;
   2755         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   2756         m_demux_entries = 0;
   2757         DEBUG_PRINT_LOW("Initialize parser");
   2758         if (m_frame_parser.mutils) {
   2759             m_frame_parser.mutils->initialize_frame_checking_environment();
   2760         }
   2761 
   2762         while (m_input_pending_q.m_size) {
   2763             m_input_pending_q.pop_entry(&p1,&p2,&ident);
   2764             m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
   2765         }
   2766 
   2767         if (psource_frame) {
   2768             m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
   2769             psource_frame = NULL;
   2770         }
   2771 
   2772         if (pdest_frame) {
   2773             pdest_frame->nFilledLen = 0;
   2774             m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned int)NULL,
   2775                     (unsigned int)NULL);
   2776             pdest_frame = NULL;
   2777         }
   2778         m_frame_parser.flush();
   2779     } else if (codec_config_flag) {
   2780         DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
   2781                 "is not sent to the driver yet");
   2782     }
   2783     pthread_mutex_unlock(&m_lock);
   2784     input_flush_progress = false;
   2785     if (!arbitrary_bytes) {
   2786         prev_ts = LLONG_MAX;
   2787         rst_prev_ts = true;
   2788     }
   2789 #ifdef _ANDROID_
   2790     if (m_debug_timestamp) {
   2791         m_timestamp_list.reset_ts_list();
   2792     }
   2793 #endif
   2794     DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
   2795     return bRet;
   2796 }
   2797 
   2798 
   2799 /* ======================================================================
   2800    FUNCTION
   2801    omx_vdec::SendCommandEvent
   2802 
   2803    DESCRIPTION
   2804    Send the event to decoder pipe.  This is needed to generate the callbacks
   2805    in decoder thread context.
   2806 
   2807    PARAMETERS
   2808    None.
   2809 
   2810    RETURN VALUE
   2811    true/false
   2812 
   2813    ========================================================================== */
   2814 bool omx_vdec::post_event(unsigned long p1,
   2815         unsigned long p2,
   2816         unsigned long id)
   2817 {
   2818     bool bRet = false;
   2819 
   2820     /* Just drop messages typically generated by hardware (w/o client request),
   2821      * if we've reported an error to client. */
   2822     if (m_error_propogated) {
   2823         switch (id) {
   2824             case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
   2825             case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
   2826                 DEBUG_PRINT_ERROR("Dropping message %lx "
   2827                         "since client expected to be in error state", id);
   2828                 return false;
   2829             default:
   2830                 /* whatever */
   2831                 break;
   2832         }
   2833     }
   2834 
   2835     pthread_mutex_lock(&m_lock);
   2836 
   2837     if (id == m_fill_output_msg ||
   2838             id == OMX_COMPONENT_GENERATE_FBD ||
   2839             id == OMX_COMPONENT_GENERATE_PORT_RECONFIG) {
   2840         m_ftb_q.insert_entry(p1,p2,id);
   2841     } else if (id == OMX_COMPONENT_GENERATE_ETB ||
   2842             id == OMX_COMPONENT_GENERATE_EBD ||
   2843             id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   2844         m_etb_q.insert_entry(p1,p2,id);
   2845     } else {
   2846         m_cmd_q.insert_entry(p1,p2,id);
   2847     }
   2848 
   2849     bRet = true;
   2850     DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
   2851     post_message(this, id);
   2852 
   2853     pthread_mutex_unlock(&m_lock);
   2854 
   2855     return bRet;
   2856 }
   2857 
   2858 OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
   2859 {
   2860     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2861     if (!profileLevelType)
   2862         return OMX_ErrorBadParameter;
   2863 
   2864     if (profileLevelType->nPortIndex == 0) {
   2865         if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   2866             if (profileLevelType->nProfileIndex == 0) {
   2867                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
   2868                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2869 
   2870             } else if (profileLevelType->nProfileIndex == 1) {
   2871                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
   2872                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2873             } else if (profileLevelType->nProfileIndex == 2) {
   2874                 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
   2875                 profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
   2876             } else {
   2877                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2878                         (unsigned int)profileLevelType->nProfileIndex);
   2879                 eRet = OMX_ErrorNoMore;
   2880             }
   2881         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   2882             if (profileLevelType->nProfileIndex == 0) {
   2883                 profileLevelType->eProfile = QOMX_VIDEO_MVCProfileStereoHigh;
   2884                 profileLevelType->eLevel   = QOMX_VIDEO_MVCLevel51;
   2885             } else {
   2886                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2887                                 (unsigned int)profileLevelType->nProfileIndex);
   2888                 eRet = OMX_ErrorNoMore;
   2889             }
   2890         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   2891             if (profileLevelType->nProfileIndex == 0) {
   2892                 profileLevelType->eProfile = OMX_VIDEO_HEVCProfileMain;
   2893                 profileLevelType->eLevel   = OMX_VIDEO_HEVCMainTierLevel51;
   2894             } else {
   2895                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2896                         (unsigned int)profileLevelType->nProfileIndex);
   2897                 eRet = OMX_ErrorNoMore;
   2898             }
   2899         } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
   2900             if (profileLevelType->nProfileIndex == 0) {
   2901                 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
   2902                 profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
   2903             } else {
   2904                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2905                                 (unsigned int)profileLevelType->nProfileIndex);
   2906                 eRet = OMX_ErrorNoMore;
   2907             }
   2908         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   2909             if (profileLevelType->nProfileIndex == 0) {
   2910                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
   2911                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   2912             } else if (profileLevelType->nProfileIndex == 1) {
   2913                 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
   2914                 profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
   2915             } else {
   2916                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2917                                 (unsigned int)profileLevelType->nProfileIndex);
   2918                 eRet = OMX_ErrorNoMore;
   2919             }
   2920         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   2921             eRet = OMX_ErrorNoMore;
   2922         } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   2923             if (profileLevelType->nProfileIndex == 0) {
   2924                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
   2925                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   2926             } else if (profileLevelType->nProfileIndex == 1) {
   2927                 profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
   2928                 profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
   2929             } else {
   2930                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %u",
   2931                                 (unsigned int)profileLevelType->nProfileIndex);
   2932                 eRet = OMX_ErrorNoMore;
   2933             }
   2934         } else {
   2935             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore for codec: %s", drv_ctx.kind);
   2936             eRet = OMX_ErrorNoMore;
   2937         }
   2938     } else {
   2939         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %u",
   2940                           (unsigned int)profileLevelType->nPortIndex);
   2941         eRet = OMX_ErrorBadPortIndex;
   2942     }
   2943     return eRet;
   2944 }
   2945 
   2946 /* ======================================================================
   2947    FUNCTION
   2948    omx_vdec::GetParameter
   2949 
   2950    DESCRIPTION
   2951    OMX Get Parameter method implementation
   2952 
   2953    PARAMETERS
   2954    <TBD>.
   2955 
   2956    RETURN VALUE
   2957    Error None if successful.
   2958 
   2959    ========================================================================== */
   2960 OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   2961         OMX_IN OMX_INDEXTYPE paramIndex,
   2962         OMX_INOUT OMX_PTR     paramData)
   2963 {
   2964     (void) hComp;
   2965     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   2966 
   2967     DEBUG_PRINT_LOW("get_parameter:");
   2968     if (m_state == OMX_StateInvalid) {
   2969         DEBUG_PRINT_ERROR("Get Param in Invalid State");
   2970         return OMX_ErrorInvalidState;
   2971     }
   2972     if (paramData == NULL) {
   2973         DEBUG_PRINT_LOW("Get Param in Invalid paramData");
   2974         return OMX_ErrorBadParameter;
   2975     }
   2976     switch ((unsigned long)paramIndex) {
   2977         case OMX_IndexParamPortDefinition: {
   2978                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
   2979                                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   2980                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition");
   2981                                eRet = update_portdef(portDefn);
   2982                                if (eRet == OMX_ErrorNone)
   2983                                    m_port_def = *portDefn;
   2984                                break;
   2985                            }
   2986         case OMX_IndexParamVideoInit: {
   2987                               OMX_PORT_PARAM_TYPE *portParamType =
   2988                                   (OMX_PORT_PARAM_TYPE *) paramData;
   2989                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit");
   2990 
   2991                               portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   2992                               portParamType->nSize = sizeof(portParamType);
   2993                               portParamType->nPorts           = 2;
   2994                               portParamType->nStartPortNumber = 0;
   2995                               break;
   2996                           }
   2997         case OMX_IndexParamVideoPortFormat: {
   2998                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   2999                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3000                                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat");
   3001 
   3002                                 portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
   3003                                 portFmt->nSize             = sizeof(portFmt);
   3004 
   3005                                 if (0 == portFmt->nPortIndex) {
   3006                                     if (0 == portFmt->nIndex) {
   3007                                         portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
   3008                                         portFmt->eCompressionFormat = eCompressionFormat;
   3009                                     } else {
   3010                                         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3011                                                 " NoMore compression formats");
   3012                                         eRet =  OMX_ErrorNoMore;
   3013                                     }
   3014                                 } else if (1 == portFmt->nPortIndex) {
   3015                                     portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
   3016 
   3017                                     // Distinguish non-surface mode from normal playback use-case based on
   3018                                     // usage hinted via "OMX.google.android.index.useAndroidNativeBuffer2"
   3019                                     // For non-android, use the default list
   3020                                     // Also use default format-list if FLEXIBLE YUV is supported,
   3021                                     // as the client negotiates the standard color-format if it needs to
   3022                                     bool useNonSurfaceMode = false;
   3023 #if defined(_ANDROID_) && !defined(FLEXYUV_SUPPORTED)
   3024                                     useNonSurfaceMode = (m_enable_android_native_buffers == OMX_FALSE);
   3025 #endif
   3026                                     portFmt->eColorFormat = useNonSurfaceMode ?
   3027                                         getPreferredColorFormatNonSurfaceMode(portFmt->nIndex) :
   3028                                         getPreferredColorFormatDefaultMode(portFmt->nIndex);
   3029 
   3030                                     if (portFmt->eColorFormat == OMX_COLOR_FormatMax ) {
   3031                                         eRet = OMX_ErrorNoMore;
   3032                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
   3033                                                 " NoMore Color formats");
   3034                                     }
   3035                                     DEBUG_PRINT_HIGH("returning color-format: 0x%x", portFmt->eColorFormat);
   3036                                 } else {
   3037                                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   3038                                             (int)portFmt->nPortIndex);
   3039                                     eRet = OMX_ErrorBadPortIndex;
   3040                                 }
   3041                                 break;
   3042                             }
   3043                             /*Component should support this port definition*/
   3044         case OMX_IndexParamAudioInit: {
   3045                               OMX_PORT_PARAM_TYPE *audioPortParamType =
   3046                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3047                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit");
   3048                               audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3049                               audioPortParamType->nSize = sizeof(audioPortParamType);
   3050                               audioPortParamType->nPorts           = 0;
   3051                               audioPortParamType->nStartPortNumber = 0;
   3052                               break;
   3053                           }
   3054                           /*Component should support this port definition*/
   3055         case OMX_IndexParamImageInit: {
   3056                               OMX_PORT_PARAM_TYPE *imagePortParamType =
   3057                                   (OMX_PORT_PARAM_TYPE *) paramData;
   3058                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit");
   3059                               imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
   3060                               imagePortParamType->nSize = sizeof(imagePortParamType);
   3061                               imagePortParamType->nPorts           = 0;
   3062                               imagePortParamType->nStartPortNumber = 0;
   3063                               break;
   3064 
   3065                           }
   3066                           /*Component should support this port definition*/
   3067         case OMX_IndexParamOtherInit: {
   3068                               DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x",
   3069                                       paramIndex);
   3070                               eRet =OMX_ErrorUnsupportedIndex;
   3071                               break;
   3072                           }
   3073         case OMX_IndexParamStandardComponentRole: {
   3074                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3075                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3076                                   comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
   3077                                   comp_role->nSize = sizeof(*comp_role);
   3078 
   3079                                   DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d",
   3080                                           paramIndex);
   3081                                   strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
   3082                                           OMX_MAX_STRINGNAME_SIZE);
   3083                                   break;
   3084                               }
   3085                               /* Added for parameter test */
   3086         case OMX_IndexParamPriorityMgmt: {
   3087 
   3088                              OMX_PRIORITYMGMTTYPE *priorityMgmType =
   3089                                  (OMX_PRIORITYMGMTTYPE *) paramData;
   3090                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt");
   3091                              priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
   3092                              priorityMgmType->nSize = sizeof(priorityMgmType);
   3093 
   3094                              break;
   3095                          }
   3096                          /* Added for parameter test */
   3097         case OMX_IndexParamCompBufferSupplier: {
   3098                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
   3099                                        (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3100                                    DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier");
   3101 
   3102                                    bufferSupplierType->nSize = sizeof(bufferSupplierType);
   3103                                    bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
   3104                                    if (0 == bufferSupplierType->nPortIndex)
   3105                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3106                                    else if (1 == bufferSupplierType->nPortIndex)
   3107                                        bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
   3108                                    else
   3109                                        eRet = OMX_ErrorBadPortIndex;
   3110 
   3111 
   3112                                    break;
   3113                                }
   3114         case OMX_IndexParamVideoAvc: {
   3115                              DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x",
   3116                                      paramIndex);
   3117                              break;
   3118                          }
   3119         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3120                              DEBUG_PRINT_LOW("get_parameter: QOMX_IndexParamVideoMvc %08x",
   3121                                      paramIndex);
   3122                              break;
   3123                          }
   3124         case OMX_IndexParamVideoH263: {
   3125                               DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   3126                                       paramIndex);
   3127                               break;
   3128                           }
   3129         case OMX_IndexParamVideoMpeg4: {
   3130                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   3131                                        paramIndex);
   3132                                break;
   3133                            }
   3134         case OMX_IndexParamVideoMpeg2: {
   3135                                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   3136                                        paramIndex);
   3137                                break;
   3138                            }
   3139         case OMX_IndexParamVideoProfileLevelQuerySupported: {
   3140                                         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", paramIndex);
   3141                                         OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
   3142                                             (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
   3143                                         eRet = get_supported_profile_level_for_1080p(profileLevelType);
   3144                                         break;
   3145                                     }
   3146 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3147         case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage: {
   3148                                         DEBUG_PRINT_LOW("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
   3149                                         GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
   3150                                         if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3151 
   3152                                             if (secure_mode && !secure_scaling_to_non_secure_opb) {
   3153                                                 nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
   3154                                                         GRALLOC_USAGE_PRIVATE_UNCACHED);
   3155                                             } else {
   3156                                                 nativeBuffersUsage->nUsage =
   3157                                                     (GRALLOC_USAGE_PRIVATE_IOMMU_HEAP |
   3158                                                      GRALLOC_USAGE_PRIVATE_UNCACHED);
   3159                                             }
   3160                                         } else {
   3161                                             DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
   3162                                             eRet = OMX_ErrorBadParameter;
   3163                                         }
   3164                                     }
   3165                                     break;
   3166 #endif
   3167 
   3168 #ifdef FLEXYUV_SUPPORTED
   3169         case OMX_QcomIndexFlexibleYUVDescription: {
   3170                 DEBUG_PRINT_LOW("get_parameter: describeColorFormat");
   3171                 eRet = describeColorFormat(paramData);
   3172                 break;
   3173             }
   3174 #endif
   3175 
   3176         default: {
   3177                  DEBUG_PRINT_ERROR("get_parameter: unknown param %08x", paramIndex);
   3178                  eRet =OMX_ErrorUnsupportedIndex;
   3179              }
   3180 
   3181     }
   3182 
   3183     DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
   3184             drv_ctx.video_resolution.frame_width,
   3185             drv_ctx.video_resolution.frame_height,
   3186             drv_ctx.video_resolution.stride,
   3187             drv_ctx.video_resolution.scan_lines);
   3188 
   3189     return eRet;
   3190 }
   3191 
   3192 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3193 OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
   3194 {
   3195     DEBUG_PRINT_LOW("Inside use_android_native_buffer");
   3196     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3197     UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
   3198 
   3199     if ((params == NULL) ||
   3200             (params->nativeBuffer == NULL) ||
   3201             (params->nativeBuffer->handle == NULL) ||
   3202             !m_enable_android_native_buffers)
   3203         return OMX_ErrorBadParameter;
   3204     m_use_android_native_buffers = OMX_TRUE;
   3205     sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   3206     private_handle_t *handle = (private_handle_t *)nBuf->handle;
   3207     if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
   3208         OMX_U8 *buffer = NULL;
   3209         if (!secure_mode) {
   3210             buffer = (OMX_U8*)mmap(0, handle->size,
   3211                     PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   3212             if (buffer == MAP_FAILED) {
   3213                 DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   3214                 return OMX_ErrorInsufficientResources;
   3215             }
   3216         }
   3217         eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
   3218     } else {
   3219         eRet = OMX_ErrorBadParameter;
   3220     }
   3221     return eRet;
   3222 }
   3223 #endif
   3224 
   3225 OMX_ERRORTYPE omx_vdec::enable_smoothstreaming() {
   3226     struct v4l2_control control;
   3227     struct v4l2_format fmt;
   3228     control.id = V4L2_CID_MPEG_VIDC_VIDEO_CONTINUE_DATA_TRANSFER;
   3229     control.value = 1;
   3230     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3231     if (rc < 0) {
   3232         DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
   3233         return OMX_ErrorHardware;
   3234     }
   3235     m_smoothstreaming_mode = true;
   3236     return OMX_ErrorNone;
   3237 }
   3238 
   3239 /* ======================================================================
   3240    FUNCTION
   3241    omx_vdec::Setparameter
   3242 
   3243    DESCRIPTION
   3244    OMX Set Parameter method implementation.
   3245 
   3246    PARAMETERS
   3247    <TBD>.
   3248 
   3249    RETURN VALUE
   3250    OMX Error None if successful.
   3251 
   3252    ========================================================================== */
   3253 OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
   3254         OMX_IN OMX_INDEXTYPE paramIndex,
   3255         OMX_IN OMX_PTR        paramData)
   3256 {
   3257     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   3258     int ret=0;
   3259     struct v4l2_format fmt;
   3260 #ifdef _ANDROID_
   3261     char property_value[PROPERTY_VALUE_MAX] = {0};
   3262 #endif
   3263     if (m_state == OMX_StateInvalid) {
   3264         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3265         return OMX_ErrorInvalidState;
   3266     }
   3267     if (paramData == NULL) {
   3268         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   3269         return OMX_ErrorBadParameter;
   3270     }
   3271     if ((m_state != OMX_StateLoaded) &&
   3272             BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
   3273             (m_out_bEnabled == OMX_TRUE) &&
   3274             BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
   3275             (m_inp_bEnabled == OMX_TRUE)) {
   3276         DEBUG_PRINT_ERROR("Set Param in Invalid State");
   3277         return OMX_ErrorIncorrectStateOperation;
   3278     }
   3279     switch ((unsigned long)paramIndex) {
   3280         case OMX_IndexParamPortDefinition: {
   3281                                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
   3282                                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
   3283                                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
   3284                                //been called.
   3285                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
   3286                                        (int)portDefn->format.video.nFrameHeight,
   3287                                        (int)portDefn->format.video.nFrameWidth);
   3288                                if (OMX_DirOutput == portDefn->eDir) {
   3289                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
   3290                                    bool port_format_changed = false;
   3291                                    m_display_id = portDefn->format.video.pNativeWindow;
   3292                                    unsigned int buffer_size;
   3293                                    /* update output port resolution with client supplied dimensions
   3294                                       in case scaling is enabled, else it follows input resolution set
   3295                                    */
   3296                                    if (is_down_scalar_enabled) {
   3297                                        DEBUG_PRINT_LOW("SetParam OP: WxH(%u x %u)",
   3298                                                (unsigned int)portDefn->format.video.nFrameWidth,
   3299                                                (unsigned int)portDefn->format.video.nFrameHeight);
   3300                                        if (portDefn->format.video.nFrameHeight != 0x0 &&
   3301                                                portDefn->format.video.nFrameWidth != 0x0) {
   3302                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3303                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3304                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3305                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   3306                                            if (ret) {
   3307                                                DEBUG_PRINT_ERROR("Get Resolution failed");
   3308                                                eRet = OMX_ErrorHardware;
   3309                                                break;
   3310                                            }
   3311                                            if ((portDefn->format.video.nFrameHeight != (unsigned int)fmt.fmt.pix_mp.height) ||
   3312                                                (portDefn->format.video.nFrameWidth != (unsigned int)fmt.fmt.pix_mp.width)) {
   3313                                                    port_format_changed = true;
   3314                                            }
   3315                                            update_resolution(portDefn->format.video.nFrameWidth,
   3316                                                    portDefn->format.video.nFrameHeight,
   3317                                                    portDefn->format.video.nFrameWidth,
   3318                                                    portDefn->format.video.nFrameHeight);
   3319 
   3320                                            /* set crop info */
   3321                                            rectangle.nLeft = 0;
   3322                                            rectangle.nTop = 0;
   3323                                            rectangle.nWidth = portDefn->format.video.nFrameWidth;
   3324                                            rectangle.nHeight = portDefn->format.video.nFrameHeight;
   3325 
   3326                                            eRet = is_video_session_supported();
   3327                                            if (eRet)
   3328                                                break;
   3329                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3330                                            fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3331                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   3332                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   3333                                            fmt.fmt.pix_mp.pixelformat = capture_capability;
   3334                                            DEBUG_PRINT_LOW("fmt.fmt.pix_mp.height = %d , fmt.fmt.pix_mp.width = %d",
   3335                                                fmt.fmt.pix_mp.height, fmt.fmt.pix_mp.width);
   3336                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   3337                                            if (ret) {
   3338                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   3339                                                eRet = OMX_ErrorUnsupportedSetting;
   3340                                            } else
   3341                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   3342                                        }
   3343 
   3344                                        if (eRet) {
   3345                                            break;
   3346                                        }
   3347 
   3348                                        if (secure_mode) {
   3349                                            struct v4l2_control control;
   3350                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SECURE_SCALING_THRESHOLD;
   3351                                            if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   3352                                                DEBUG_PRINT_ERROR("Failed getting secure scaling threshold : %d, id was : %x", errno, control.id);
   3353                                                eRet = OMX_ErrorHardware;
   3354                                            } else {
   3355                                                /* This is a workaround for a bug in fw which uses stride
   3356                                                 * and slice instead of width and height to check against
   3357                                                 * the threshold.
   3358                                                 */
   3359                                                OMX_U32 stride, slice;
   3360                                                if (drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   3361                                                    stride = VENUS_Y_STRIDE(COLOR_FMT_NV12, portDefn->format.video.nFrameWidth);
   3362                                                    slice = VENUS_Y_SCANLINES(COLOR_FMT_NV12, portDefn->format.video.nFrameHeight);
   3363                                                } else {
   3364                                                    stride = portDefn->format.video.nFrameWidth;
   3365                                                    slice = portDefn->format.video.nFrameHeight;
   3366                                                }
   3367 
   3368                                                DEBUG_PRINT_LOW("Stride is %d, slice is %d, sxs is %d\n", stride, slice, stride * slice);
   3369                                                DEBUG_PRINT_LOW("Threshold value is %d\n", control.value);
   3370 
   3371                                                if (stride * slice <= (OMX_U32)control.value) {
   3372                                                    secure_scaling_to_non_secure_opb = true;
   3373                                                    DEBUG_PRINT_HIGH("Enabling secure scalar out of CPZ");
   3374                                                    control.id = V4L2_CID_MPEG_VIDC_VIDEO_NON_SECURE_OUTPUT2;
   3375                                                    control.value = 1;
   3376                                                    if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) {
   3377                                                        DEBUG_PRINT_ERROR("Enabling non-secure output2 failed");
   3378                                                        eRet = OMX_ErrorUnsupportedSetting;
   3379                                                    }
   3380                                    }
   3381                                            }
   3382                                        }
   3383                                    }
   3384 
   3385                                    if (eRet) {
   3386                                        break;
   3387                                    }
   3388 
   3389                                    if (!client_buffers.get_buffer_req(buffer_size)) {
   3390                                        DEBUG_PRINT_ERROR("Error in getting buffer requirements");
   3391                                        eRet = OMX_ErrorBadParameter;
   3392                                    } else if (!port_format_changed) {
   3393                                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
   3394                                                portDefn->nBufferSize >=  drv_ctx.op_buf.buffer_size ) {
   3395                                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
   3396                                            drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
   3397                                            drv_ctx.extradata_info.count = drv_ctx.op_buf.actualcount;
   3398                                            drv_ctx.extradata_info.size = drv_ctx.extradata_info.count *
   3399                                                drv_ctx.extradata_info.buffer_size;
   3400                                            eRet = set_buffer_req(&drv_ctx.op_buf);
   3401                                            if (eRet == OMX_ErrorNone)
   3402                                                m_port_def = *portDefn;
   3403                                        } else {
   3404                                            DEBUG_PRINT_ERROR("ERROR: OP Requirements(#%d: %u) Requested(#%u: %u)",
   3405                                                    drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size,
   3406                                                    (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   3407                                            eRet = OMX_ErrorBadParameter;
   3408                                        }
   3409                                    }
   3410                                } else if (OMX_DirInput == portDefn->eDir) {
   3411                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
   3412                                    bool port_format_changed = false;
   3413                                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
   3414                                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
   3415                                        // Frame rate only should be set if this is a "known value" or to
   3416                                        // activate ts prediction logic (arbitrary mode only) sending input
   3417                                        // timestamps with max value (LLONG_MAX).
   3418                                        DEBUG_PRINT_HIGH("set_parameter: frame rate set by omx client : %u",
   3419                                                (unsigned int)portDefn->format.video.xFramerate >> 16);
   3420                                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
   3421                                                drv_ctx.frame_rate.fps_denominator);
   3422                                        if (!drv_ctx.frame_rate.fps_numerator) {
   3423                                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   3424                                            drv_ctx.frame_rate.fps_numerator = 30;
   3425                                        }
   3426                                        if (drv_ctx.frame_rate.fps_denominator)
   3427                                            drv_ctx.frame_rate.fps_numerator = (int)
   3428                                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   3429                                        drv_ctx.frame_rate.fps_denominator = 1;
   3430                                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   3431                                            drv_ctx.frame_rate.fps_numerator;
   3432                                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
   3433                                                (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   3434                                                (float)drv_ctx.frame_rate.fps_denominator);
   3435 
   3436                                        struct v4l2_outputparm oparm;
   3437                                        /*XXX: we're providing timing info as seconds per frame rather than frames
   3438                                         * per second.*/
   3439                                        oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   3440                                        oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   3441 
   3442                                        struct v4l2_streamparm sparm;
   3443                                        sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3444                                        sparm.parm.output = oparm;
   3445                                        if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   3446                                            DEBUG_PRINT_ERROR("Unable to convey fps info to driver, performance might be affected");
   3447                                            eRet = OMX_ErrorHardware;
   3448                                            break;
   3449                                    }
   3450                                        //m_perf_control.request_cores(frm_int);
   3451                                    }
   3452 
   3453                                    if (drv_ctx.video_resolution.frame_height !=
   3454                                            portDefn->format.video.nFrameHeight ||
   3455                                            drv_ctx.video_resolution.frame_width  !=
   3456                                            portDefn->format.video.nFrameWidth) {
   3457                                        DEBUG_PRINT_LOW("SetParam IP: WxH(%u x %u)",
   3458                                                (unsigned int)portDefn->format.video.nFrameWidth,
   3459                                                (unsigned int)portDefn->format.video.nFrameHeight);
   3460                                        port_format_changed = true;
   3461                                        OMX_U32 frameWidth = portDefn->format.video.nFrameWidth;
   3462                                        OMX_U32 frameHeight = portDefn->format.video.nFrameHeight;
   3463                                        if (frameHeight != 0x0 && frameWidth != 0x0) {
   3464                                            if (m_smoothstreaming_mode &&
   3465                                                    ((frameWidth * frameHeight) <
   3466                                                    (m_smoothstreaming_width * m_smoothstreaming_height))) {
   3467                                                frameWidth = m_smoothstreaming_width;
   3468                                                frameHeight = m_smoothstreaming_height;
   3469                                                DEBUG_PRINT_LOW("NOTE: Setting resolution %u x %u "
   3470                                                        "for adaptive-playback/smooth-streaming",
   3471                                                        (unsigned int)frameWidth, (unsigned int)frameHeight);
   3472                                            }
   3473                                            update_resolution(frameWidth, frameHeight,
   3474                                                    frameWidth, frameHeight);
   3475                                            eRet = is_video_session_supported();
   3476                                            if (eRet)
   3477                                                break;
   3478                                            memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3479                                            fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   3480                                            fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   3481                                            fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   3482                                            fmt.fmt.pix_mp.pixelformat = output_capability;
   3483                                            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);
   3484                                            ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   3485                                            if (ret) {
   3486                                                DEBUG_PRINT_ERROR("Set Resolution failed");
   3487                                                eRet = OMX_ErrorUnsupportedSetting;
   3488                                            } else {
   3489                                                if (!is_down_scalar_enabled)
   3490                                                eRet = get_buffer_req(&drv_ctx.op_buf);
   3491                                        }
   3492                                    }
   3493                                    }
   3494                                    if (m_custom_buffersize.input_buffersize
   3495                                         && (portDefn->nBufferSize > m_custom_buffersize.input_buffersize)) {
   3496                                        DEBUG_PRINT_ERROR("ERROR: Custom buffer size set by client: %d, trying to set: %d",
   3497                                                m_custom_buffersize.input_buffersize, portDefn->nBufferSize);
   3498                                        eRet = OMX_ErrorBadParameter;
   3499                                        break;
   3500                                    }
   3501                                    if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
   3502                                            || portDefn->nBufferSize != drv_ctx.ip_buf.buffer_size) {
   3503                                        port_format_changed = true;
   3504                                        vdec_allocatorproperty *buffer_prop = &drv_ctx.ip_buf;
   3505                                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
   3506                                        drv_ctx.ip_buf.buffer_size = (portDefn->nBufferSize + buffer_prop->alignment - 1) &
   3507                                            (~(buffer_prop->alignment - 1));
   3508                                        eRet = set_buffer_req(buffer_prop);
   3509                                    }
   3510                                    if (false == port_format_changed) {
   3511                                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%u: %u)",
   3512                                                drv_ctx.ip_buf.mincount, (unsigned int)drv_ctx.ip_buf.buffer_size,
   3513                                                (unsigned int)portDefn->nBufferCountActual, (unsigned int)portDefn->nBufferSize);
   3514                                        eRet = OMX_ErrorBadParameter;
   3515                                    }
   3516                                } else if (portDefn->eDir ==  OMX_DirMax) {
   3517                                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
   3518                                            (int)portDefn->nPortIndex);
   3519                                    eRet = OMX_ErrorBadPortIndex;
   3520                                }
   3521                            }
   3522                            break;
   3523         case OMX_IndexParamVideoPortFormat: {
   3524                                 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
   3525                                     (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
   3526                                 int ret=0;
   3527                                 struct v4l2_format fmt;
   3528                                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoPortFormat 0x%x, port: %u",
   3529                                         portFmt->eColorFormat, (unsigned int)portFmt->nPortIndex);
   3530 
   3531                                 memset(&fmt, 0x0, sizeof(struct v4l2_format));
   3532                                 if (1 == portFmt->nPortIndex) {
   3533                                     fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   3534                                     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   3535                                     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   3536                                     fmt.fmt.pix_mp.pixelformat = capture_capability;
   3537                                     enum vdec_output_fromat op_format;
   3538                                     if (portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   3539                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
   3540                                             portFmt->eColorFormat == (OMX_COLOR_FORMATTYPE)
   3541                                                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView ||
   3542                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar ||
   3543                                             portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
   3544                                         op_format = (enum vdec_output_fromat)VDEC_YUV_FORMAT_NV12;
   3545                                     else
   3546                                         eRet = OMX_ErrorBadParameter;
   3547 
   3548                                     if (eRet == OMX_ErrorNone) {
   3549                                         drv_ctx.output_format = op_format;
   3550                                         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   3551                                         if (ret) {
   3552                                             DEBUG_PRINT_ERROR("Set output format failed");
   3553                                             eRet = OMX_ErrorUnsupportedSetting;
   3554                                             /*TODO: How to handle this case */
   3555                                         } else {
   3556                                             eRet = get_buffer_req(&drv_ctx.op_buf);
   3557                                         }
   3558                                     }
   3559                                     if (eRet == OMX_ErrorNone) {
   3560                                         if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
   3561                                             DEBUG_PRINT_ERROR("Set color format failed");
   3562                                             eRet = OMX_ErrorBadParameter;
   3563                                         }
   3564                                     }
   3565                                 }
   3566                             }
   3567                             break;
   3568 
   3569         case OMX_QcomIndexPortDefn: {
   3570                             OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
   3571                                 (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
   3572                             DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %u",
   3573                                     (unsigned int)portFmt->nFramePackingFormat);
   3574 
   3575                             /* Input port */
   3576                             if (portFmt->nPortIndex == 0) {
   3577                                 if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
   3578                                     if (secure_mode) {
   3579                                         arbitrary_bytes = false;
   3580                                         DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
   3581                                         eRet = OMX_ErrorUnsupportedSetting;
   3582                                     } else {
   3583                                         arbitrary_bytes = true;
   3584                                     }
   3585                                 } else if (portFmt->nFramePackingFormat ==
   3586                                         OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
   3587                                     arbitrary_bytes = false;
   3588 #ifdef _ANDROID_
   3589                                     property_get("vidc.dec.debug.arbitrarybytes.mode", property_value, "0");
   3590                                     if (atoi(property_value)) {
   3591                                         DEBUG_PRINT_HIGH("arbitrary_bytes enabled via property command");
   3592                                         arbitrary_bytes = true;
   3593                                     }
   3594 #endif
   3595                                 } else {
   3596                                     DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %u",
   3597                                             (unsigned int)portFmt->nFramePackingFormat);
   3598                                     eRet = OMX_ErrorUnsupportedSetting;
   3599                                 }
   3600                             } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3601                                 DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
   3602                                 if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
   3603                                             portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
   3604                                         portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
   3605                                     m_out_mem_region_smi = OMX_TRUE;
   3606                                     if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   3607                                         DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: out pmem set");
   3608                                         m_use_output_pmem = OMX_TRUE;
   3609                                     }
   3610                                 }
   3611                             }
   3612                         }
   3613                         break;
   3614 
   3615         case OMX_IndexParamStandardComponentRole: {
   3616                                   OMX_PARAM_COMPONENTROLETYPE *comp_role;
   3617                                   comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
   3618                                   DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
   3619                                           comp_role->cRole);
   3620 
   3621                                   if ((m_state == OMX_StateLoaded)&&
   3622                                           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   3623                                       DEBUG_PRINT_LOW("Set Parameter called in valid state");
   3624                                   } else {
   3625                                       DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   3626                                       return OMX_ErrorIncorrectStateOperation;
   3627                                   }
   3628 
   3629                                   if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3630                                       if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   3631                                           strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   3632                                       } else {
   3633                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3634                                           eRet =OMX_ErrorUnsupportedSetting;
   3635                                       }
   3636                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3637                                       if (!strncmp((char*)comp_role->cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   3638                                           strlcpy((char*)m_cRole, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   3639                                       } else {
   3640                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3641                                           eRet =OMX_ErrorUnsupportedSetting;
   3642                                       }
   3643                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3644                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   3645                                           strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   3646                                       } else {
   3647                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3648                                           eRet = OMX_ErrorUnsupportedSetting;
   3649                                       }
   3650                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3651                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   3652                                           strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   3653                                       } else {
   3654                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3655                                           eRet =OMX_ErrorUnsupportedSetting;
   3656                                       }
   3657                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3658                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   3659                                           strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   3660                                       } else {
   3661                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3662                                           eRet = OMX_ErrorUnsupportedSetting;
   3663                                       }
   3664                                   } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   3665                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311", OMX_MAX_STRINGNAME_SIZE)) ||
   3666                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4", OMX_MAX_STRINGNAME_SIZE))
   3667                                         ) {
   3668                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
   3669                                           strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   3670                                       } else {
   3671                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3672                                           eRet =OMX_ErrorUnsupportedSetting;
   3673                                       }
   3674                                   } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   3675                                           (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   3676                                         ) {
   3677                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
   3678                                           strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   3679                                       } else {
   3680                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3681                                           eRet =OMX_ErrorUnsupportedSetting;
   3682                                       }
   3683                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   3684                                       if (!strncmp((const char*)comp_role->cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE) ||
   3685                                               (!strncmp((const char*)comp_role->cRole,"video_decoder.vpx",OMX_MAX_STRINGNAME_SIZE))) {
   3686                                           strlcpy((char*)m_cRole,"video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   3687                                       } else {
   3688                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3689                                           eRet = OMX_ErrorUnsupportedSetting;
   3690                                       }
   3691                                   } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3692                                       if (!strncmp((const char*)comp_role->cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   3693                                           strlcpy((char*)m_cRole, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   3694                                   } else {
   3695                                           DEBUG_PRINT_ERROR("Setparameter: unknown Index %s", comp_role->cRole);
   3696                                           eRet = OMX_ErrorUnsupportedSetting;
   3697                                       }
   3698                                   } else {
   3699                                       DEBUG_PRINT_ERROR("Setparameter: unknown param %s", drv_ctx.kind);
   3700                                       eRet = OMX_ErrorInvalidComponentName;
   3701                                   }
   3702                                   break;
   3703                               }
   3704 
   3705         case OMX_IndexParamPriorityMgmt: {
   3706                              if (m_state != OMX_StateLoaded) {
   3707                                  DEBUG_PRINT_ERROR("Set Parameter called in Invalid State");
   3708                                  return OMX_ErrorIncorrectStateOperation;
   3709                              }
   3710                              OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   3711                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %u",
   3712                                      (unsigned int)priorityMgmtype->nGroupID);
   3713 
   3714                              DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %u",
   3715                                      (unsigned int)priorityMgmtype->nGroupPriority);
   3716 
   3717                              m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
   3718                              m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
   3719 
   3720                              break;
   3721                          }
   3722 
   3723         case OMX_IndexParamCompBufferSupplier: {
   3724                                    OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
   3725                                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d",
   3726                                            bufferSupplierType->eBufferSupplier);
   3727                                    if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
   3728                                        m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
   3729 
   3730                                    else
   3731 
   3732                                        eRet = OMX_ErrorBadPortIndex;
   3733 
   3734                                    break;
   3735 
   3736                                }
   3737         case OMX_IndexParamVideoAvc: {
   3738                              DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d",
   3739                                      paramIndex);
   3740                              break;
   3741                          }
   3742         case (OMX_INDEXTYPE)QOMX_IndexParamVideoMvc: {
   3743                             DEBUG_PRINT_LOW("set_parameter: QOMX_IndexParamVideoMvc %d",
   3744                                      paramIndex);
   3745                              break;
   3746                          }
   3747         case OMX_IndexParamVideoH263: {
   3748                               DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   3749                                       paramIndex);
   3750                               break;
   3751                           }
   3752         case OMX_IndexParamVideoMpeg4: {
   3753                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   3754                                        paramIndex);
   3755                                break;
   3756                            }
   3757         case OMX_IndexParamVideoMpeg2: {
   3758                                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   3759                                        paramIndex);
   3760                                break;
   3761                            }
   3762         case OMX_QcomIndexParamVideoDecoderPictureOrder: {
   3763                                      QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
   3764                                          (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
   3765                                      struct v4l2_control control;
   3766                                      int pic_order,rc=0;
   3767                                      DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d",
   3768                                              pictureOrder->eOutputPictureOrder);
   3769                                      if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER) {
   3770                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DISPLAY;
   3771                                      } else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
   3772                                          pic_order = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   3773                                          time_stamp_dts.set_timestamp_reorder_mode(false);
   3774                                      } else
   3775                                          eRet = OMX_ErrorBadParameter;
   3776                                      if (eRet == OMX_ErrorNone) {
   3777                                          control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   3778                                          control.value = pic_order;
   3779                                          rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3780                                          if (rc) {
   3781                                              DEBUG_PRINT_ERROR("Set picture order failed");
   3782                                              eRet = OMX_ErrorUnsupportedSetting;
   3783                                          }
   3784                                      }
   3785                                      break;
   3786                                  }
   3787         case OMX_QcomIndexParamConcealMBMapExtraData:
   3788                                      eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP, false,
   3789                                              ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3790                                  break;
   3791         case OMX_QcomIndexParamFrameInfoExtraData:
   3792                                        eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA, false,
   3793                                                ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3794                                    break;
   3795         case OMX_ExtraDataFrameDimension:
   3796                                eRet = enable_extradata(OMX_FRAMEDIMENSION_EXTRADATA, false,
   3797                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3798                                break;
   3799         case OMX_QcomIndexParamInterlaceExtraData:
   3800                                    eRet = enable_extradata(OMX_INTERLACE_EXTRADATA, false,
   3801                                            ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3802                                break;
   3803         case OMX_QcomIndexParamH264TimeInfo:
   3804                                    eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA, false,
   3805                                            ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3806                                break;
   3807         case OMX_QcomIndexParamVideoFramePackingExtradata:
   3808                                eRet = enable_extradata(OMX_FRAMEPACK_EXTRADATA, false,
   3809                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3810                                break;
   3811         case OMX_QcomIndexParamVideoQPExtraData:
   3812                                eRet = enable_extradata(OMX_QP_EXTRADATA, false,
   3813                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3814                                break;
   3815         case OMX_QcomIndexParamVideoInputBitsInfoExtraData:
   3816                                eRet = enable_extradata(OMX_BITSINFO_EXTRADATA, false,
   3817                                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3818                                break;
   3819         case OMX_QcomIndexEnableExtnUserData:
   3820                                 eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA, false,
   3821                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3822                                break;
   3823         case OMX_QcomIndexParamMpeg2SeqDispExtraData:
   3824                                 eRet = enable_extradata(OMX_MPEG2SEQDISP_EXTRADATA, false,
   3825                                     ((QOMX_ENABLETYPE *)paramData)->bEnable);
   3826                                 break;
   3827         case OMX_QcomIndexParamVideoDivx: {
   3828                               QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
   3829                           }
   3830                           break;
   3831         case OMX_QcomIndexPlatformPvt: {
   3832                                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
   3833                                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
   3834                                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   3835                                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
   3836                                    eRet = OMX_ErrorUnsupportedSetting;
   3837                                } else {
   3838                                    m_out_pvt_entry_pmem = OMX_TRUE;
   3839                                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
   3840                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: out pmem set");
   3841                                        m_use_output_pmem = OMX_TRUE;
   3842                                    }
   3843                                }
   3844 
   3845                            }
   3846                            break;
   3847         case OMX_QcomIndexParamVideoSyncFrameDecodingMode: {
   3848                                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
   3849                                        DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
   3850                                        struct v4l2_control control;
   3851                                        int rc;
   3852                                        drv_ctx.idr_only_decoding = 1;
   3853                                        control.id = V4L2_CID_MPEG_VIDC_VIDEO_OUTPUT_ORDER;
   3854                                        control.value = V4L2_MPEG_VIDC_VIDEO_OUTPUT_ORDER_DECODE;
   3855                                        rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3856                                        if (rc) {
   3857                                            DEBUG_PRINT_ERROR("Set picture order failed");
   3858                                            eRet = OMX_ErrorUnsupportedSetting;
   3859                                        } else {
   3860                                            control.id = V4L2_CID_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE;
   3861                                            control.value = V4L2_MPEG_VIDC_VIDEO_SYNC_FRAME_DECODE_ENABLE;
   3862                                            rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   3863                                            if (rc) {
   3864                                                DEBUG_PRINT_ERROR("Sync frame setting failed");
   3865                                                eRet = OMX_ErrorUnsupportedSetting;
   3866                                            }
   3867                                            /*Setting sync frame decoding on driver might change buffer
   3868                                             * requirements so update them here*/
   3869                                            if (get_buffer_req(&drv_ctx.ip_buf)) {
   3870                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer i/p requirements");
   3871                                                eRet = OMX_ErrorUnsupportedSetting;
   3872                                            }
   3873                                            if (get_buffer_req(&drv_ctx.op_buf)) {
   3874                                                DEBUG_PRINT_ERROR("Sync frame setting failed: falied to get buffer o/p requirements");
   3875                                                eRet = OMX_ErrorUnsupportedSetting;
   3876                                            }
   3877                                        }
   3878                                    }
   3879                                    break;
   3880 
   3881         case OMX_QcomIndexParamIndexExtraDataType: {
   3882                                        QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
   3883                                        if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
   3884                                                (extradataIndexType->bEnabled == OMX_TRUE) &&
   3885                                                (extradataIndexType->nPortIndex == 1)) {
   3886                                         DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
   3887                                            eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, false, extradataIndexType->bEnabled);
   3888 
   3889                                        }
   3890                                    }
   3891                                break;
   3892         case OMX_QcomIndexParamEnableSmoothStreaming: {
   3893 #ifndef SMOOTH_STREAMING_DISABLED
   3894                                       eRet = enable_smoothstreaming();
   3895 #else
   3896                                       eRet = OMX_ErrorUnsupportedSetting;
   3897 #endif
   3898                                   }
   3899                                   break;
   3900 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   3901                                   /* Need to allow following two set_parameters even in Idle
   3902                                    * state. This is ANDROID architecture which is not in sync
   3903                                    * with openmax standard. */
   3904         case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers: {
   3905                                            EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
   3906                                            if (enableNativeBuffers) {
   3907                                                m_enable_android_native_buffers = enableNativeBuffers->enable;
   3908                                            }
   3909 #if !defined(FLEXYUV_SUPPORTED)
   3910                                            if (m_enable_android_native_buffers) {
   3911                                                // Use the most-preferred-native-color-format as surface-mode is hinted here
   3912                                                if(!client_buffers.set_color_format(getPreferredColorFormatDefaultMode(0))) {
   3913                                                    DEBUG_PRINT_ERROR("Failed to set native color format!");
   3914                                                    eRet = OMX_ErrorUnsupportedSetting;
   3915                                                }
   3916                                            }
   3917 #endif
   3918                                        }
   3919                                        break;
   3920         case OMX_GoogleAndroidIndexUseAndroidNativeBuffer: {
   3921                                        eRet = use_android_native_buffer(hComp, paramData);
   3922                                    }
   3923                                    break;
   3924 #endif
   3925         case OMX_QcomIndexParamEnableTimeStampReorder: {
   3926                                        QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
   3927                                        if (drv_ctx.picture_order == (vdec_output_order)QOMX_VIDEO_DISPLAY_ORDER) {
   3928                                            if (reorder->bEnable == OMX_TRUE) {
   3929                                                frm_int =0;
   3930                                                time_stamp_dts.set_timestamp_reorder_mode(true);
   3931                                            } else
   3932                                                time_stamp_dts.set_timestamp_reorder_mode(false);
   3933                                        } else {
   3934                                            time_stamp_dts.set_timestamp_reorder_mode(false);
   3935                                            if (reorder->bEnable == OMX_TRUE) {
   3936                                                eRet = OMX_ErrorUnsupportedSetting;
   3937                                            }
   3938                                        }
   3939                                    }
   3940                                    break;
   3941         case OMX_IndexParamVideoProfileLevelCurrent: {
   3942                                      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam =
   3943                                          (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
   3944                                      if (pParam) {
   3945                                          m_profile_lvl.eProfile = pParam->eProfile;
   3946                                          m_profile_lvl.eLevel = pParam->eLevel;
   3947                                      }
   3948                                      break;
   3949 
   3950                                  }
   3951         case OMX_QcomIndexParamVideoMetaBufferMode:
   3952         {
   3953             StoreMetaDataInBuffersParams *metabuffer =
   3954                 (StoreMetaDataInBuffersParams *)paramData;
   3955             if (!metabuffer) {
   3956                 DEBUG_PRINT_ERROR("Invalid param: %p", metabuffer);
   3957                 eRet = OMX_ErrorBadParameter;
   3958                 break;
   3959             }
   3960             if (m_disable_dynamic_buf_mode) {
   3961                 DEBUG_PRINT_HIGH("Dynamic buffer mode disabled by setprop");
   3962                 eRet = OMX_ErrorUnsupportedSetting;
   3963                 break;
   3964             }
   3965             if (metabuffer->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   3966                     //set property dynamic buffer mode to driver.
   3967                     struct v4l2_control control;
   3968                     struct v4l2_format fmt;
   3969                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_ALLOC_MODE_OUTPUT;
   3970                     if (metabuffer->bStoreMetaData == true) {
   3971                     control.value = V4L2_MPEG_VIDC_VIDEO_DYNAMIC;
   3972                     } else {
   3973                         control.value = V4L2_MPEG_VIDC_VIDEO_STATIC;
   3974                     }
   3975                     int rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL,&control);
   3976                     if (!rc) {
   3977                         DEBUG_PRINT_HIGH("%s buffer mode",
   3978                            (metabuffer->bStoreMetaData == true)? "Enabled dynamic" : "Disabled dynamic");
   3979                                dynamic_buf_mode = metabuffer->bStoreMetaData;
   3980                     } else {
   3981                         DEBUG_PRINT_ERROR("Failed to %s buffer mode",
   3982                            (metabuffer->bStoreMetaData == true)? "enable dynamic" : "disable dynamic");
   3983                         eRet = OMX_ErrorUnsupportedSetting;
   3984                     }
   3985                 } else {
   3986                     DEBUG_PRINT_ERROR(
   3987                        "OMX_QcomIndexParamVideoMetaBufferMode not supported for port: %u",
   3988                        (unsigned int)metabuffer->nPortIndex);
   3989                     eRet = OMX_ErrorUnsupportedSetting;
   3990                 }
   3991                 break;
   3992         }
   3993         case OMX_QcomIndexParamVideoDownScalar:
   3994         {
   3995             QOMX_INDEXDOWNSCALAR* pParam = (QOMX_INDEXDOWNSCALAR*)paramData;
   3996             struct v4l2_control control;
   3997             int rc;
   3998             if (pParam) {
   3999                 is_down_scalar_enabled = pParam->bEnable;
   4000                 if (is_down_scalar_enabled) {
   4001                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_MODE;
   4002                     control.value = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_OUTPUT_SECONDARY;
   4003                     DEBUG_PRINT_LOW("set_parameter:  OMX_QcomIndexParamVideoDownScalar value = %d", pParam->bEnable);
   4004                     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4005                     if (rc < 0) {
   4006                         DEBUG_PRINT_ERROR("Failed to set down scalar on driver.");
   4007                         eRet = OMX_ErrorUnsupportedSetting;
   4008                     }
   4009                     control.id = V4L2_CID_MPEG_VIDC_VIDEO_KEEP_ASPECT_RATIO;
   4010                     control.value = 1;
   4011                     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control);
   4012                     if (rc < 0) {
   4013                         DEBUG_PRINT_ERROR("Failed to set keep aspect ratio on driver.");
   4014                         eRet = OMX_ErrorUnsupportedSetting;
   4015                     }
   4016                 }
   4017             }
   4018             break;
   4019         }
   4020 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   4021         case OMX_QcomIndexParamVideoAdaptivePlaybackMode:
   4022         {
   4023             DEBUG_PRINT_LOW("set_parameter: OMX_GoogleAndroidIndexPrepareForAdaptivePlayback");
   4024             PrepareForAdaptivePlaybackParams* pParams =
   4025                     (PrepareForAdaptivePlaybackParams *) paramData;
   4026             if (pParams->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
   4027                 if (!pParams->bEnable) {
   4028                     return OMX_ErrorNone;
   4029                 }
   4030                 if (pParams->nMaxFrameWidth > maxSmoothStreamingWidth
   4031                         || pParams->nMaxFrameHeight > maxSmoothStreamingHeight) {
   4032                     DEBUG_PRINT_ERROR(
   4033                             "Adaptive playback request exceeds max supported resolution : [%u x %u] vs [%u x %u]",
   4034                              (unsigned int)pParams->nMaxFrameWidth, (unsigned int)pParams->nMaxFrameHeight,
   4035                              (unsigned int)maxSmoothStreamingWidth, (unsigned int)maxSmoothStreamingHeight);
   4036                     eRet = OMX_ErrorBadParameter;
   4037                 } else {
   4038                     eRet = enable_adaptive_playback(pParams->nMaxFrameWidth, pParams->nMaxFrameHeight);
   4039                  }
   4040             } else {
   4041                 DEBUG_PRINT_ERROR(
   4042                         "Prepare for adaptive playback supported only on output port");
   4043                 eRet = OMX_ErrorBadParameter;
   4044             }
   4045             break;
   4046         }
   4047 
   4048 #endif
   4049         case OMX_QcomIndexParamVideoCustomBufferSize:
   4050         {
   4051             DEBUG_PRINT_LOW("set_parameter: OMX_QcomIndexParamVideoCustomBufferSize");
   4052             QOMX_VIDEO_CUSTOM_BUFFERSIZE* pParam = (QOMX_VIDEO_CUSTOM_BUFFERSIZE*)paramData;
   4053             if (pParam->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   4054                 struct v4l2_control control;
   4055                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_BUFFER_SIZE_LIMIT;
   4056                 control.value = pParam->nBufferSize;
   4057                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   4058                     DEBUG_PRINT_ERROR("Failed to set input buffer size");
   4059                     eRet = OMX_ErrorUnsupportedSetting;
   4060                 } else {
   4061                     eRet = get_buffer_req(&drv_ctx.ip_buf);
   4062                     if (eRet == OMX_ErrorNone) {
   4063                         m_custom_buffersize.input_buffersize = drv_ctx.ip_buf.buffer_size;
   4064                         DEBUG_PRINT_HIGH("Successfully set custom input buffer size = %d",
   4065                             m_custom_buffersize.input_buffersize);
   4066                     } else {
   4067                         DEBUG_PRINT_ERROR("Failed to get buffer requirement");
   4068                     }
   4069                 }
   4070             } else {
   4071                 DEBUG_PRINT_ERROR("ERROR: Custom buffer size in not supported on output port");
   4072                 eRet = OMX_ErrorBadParameter;
   4073             }
   4074             break;
   4075         }
   4076         default: {
   4077                  DEBUG_PRINT_ERROR("Setparameter: unknown param %d", paramIndex);
   4078                  eRet = OMX_ErrorUnsupportedIndex;
   4079              }
   4080     }
   4081     if (eRet != OMX_ErrorNone)
   4082         DEBUG_PRINT_ERROR("set_parameter: Error: 0x%x, setting param 0x%x", eRet, paramIndex);
   4083     return eRet;
   4084 }
   4085 
   4086 /* ======================================================================
   4087    FUNCTION
   4088    omx_vdec::GetConfig
   4089 
   4090    DESCRIPTION
   4091    OMX Get Config Method implementation.
   4092 
   4093    PARAMETERS
   4094    <TBD>.
   4095 
   4096    RETURN VALUE
   4097    OMX Error None if successful.
   4098 
   4099    ========================================================================== */
   4100 OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
   4101         OMX_IN OMX_INDEXTYPE configIndex,
   4102         OMX_INOUT OMX_PTR     configData)
   4103 {
   4104     (void) hComp;
   4105     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4106 
   4107     if (m_state == OMX_StateInvalid) {
   4108         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   4109         return OMX_ErrorInvalidState;
   4110     }
   4111 
   4112     switch ((unsigned long)configIndex) {
   4113         case OMX_QcomIndexConfigInterlaced: {
   4114                                 OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
   4115                                     (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
   4116                                 if (configFmt->nPortIndex == 1) {
   4117                                     if (configFmt->nIndex == 0) {
   4118                                         configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
   4119                                     } else if (configFmt->nIndex == 1) {
   4120                                         configFmt->eInterlaceType =
   4121                                             OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   4122                                     } else if (configFmt->nIndex == 2) {
   4123                                         configFmt->eInterlaceType =
   4124                                             OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   4125                                     } else {
   4126                                         DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
   4127                                                 " NoMore Interlaced formats");
   4128                                         eRet = OMX_ErrorNoMore;
   4129                                     }
   4130 
   4131                                 } else {
   4132                                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
   4133                                             (int)configFmt->nPortIndex);
   4134                                     eRet = OMX_ErrorBadPortIndex;
   4135                                 }
   4136                                 break;
   4137                             }
   4138         case OMX_QcomIndexQueryNumberOfVideoDecInstance: {
   4139                                      QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
   4140                                          (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
   4141                                      decoderinstances->nNumOfInstances = 16;
   4142                                      /*TODO: How to handle this case */
   4143                                      break;
   4144                                  }
   4145         case OMX_QcomIndexConfigVideoFramePackingArrangement: {
   4146                                           if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
   4147                                               OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
   4148                                                   (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
   4149                                               memcpy(configFmt, &m_frame_pack_arrangement,
   4150                                                   sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   4151                                           } else {
   4152                                               DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
   4153                                           }
   4154                                           break;
   4155                                       }
   4156         case OMX_IndexConfigCommonOutputCrop: {
   4157                                   OMX_CONFIG_RECTTYPE *rect = (OMX_CONFIG_RECTTYPE *) configData;
   4158                                   memcpy(rect, &rectangle, sizeof(OMX_CONFIG_RECTTYPE));
   4159                                   DEBUG_PRINT_HIGH("get_config: crop info: L: %u, T: %u, R: %u, B: %u",
   4160                                         rectangle.nLeft, rectangle.nTop,
   4161                                         rectangle.nWidth, rectangle.nHeight);
   4162                                   break;
   4163                               }
   4164         case OMX_QcomIndexConfigPerfLevel: {
   4165                 struct v4l2_control control;
   4166                 OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   4167                         (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   4168 
   4169                 control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   4170                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_G_CTRL, &control) < 0) {
   4171                     DEBUG_PRINT_ERROR("Failed getting performance level: %d", errno);
   4172                     eRet = OMX_ErrorHardware;
   4173                 }
   4174 
   4175                 if (eRet == OMX_ErrorNone) {
   4176                     switch (control.value) {
   4177                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO:
   4178                             perf->ePerfLevel = OMX_QCOM_PerfLevelTurbo;
   4179                             break;
   4180                         default:
   4181                             DEBUG_PRINT_HIGH("Unknown perf level %d, reporting Nominal instead", control.value);
   4182                             /* Fall through */
   4183                         case V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL:
   4184                             perf->ePerfLevel = OMX_QCOM_PerfLevelNominal;
   4185                             break;
   4186                     }
   4187                 }
   4188 
   4189                                   break;
   4190                               }
   4191         default: {
   4192                  DEBUG_PRINT_ERROR("get_config: unknown param %d",configIndex);
   4193                  eRet = OMX_ErrorBadParameter;
   4194              }
   4195 
   4196     }
   4197 
   4198     return eRet;
   4199 }
   4200 
   4201 /* ======================================================================
   4202    FUNCTION
   4203    omx_vdec::SetConfig
   4204 
   4205    DESCRIPTION
   4206    OMX Set Config method implementation
   4207 
   4208    PARAMETERS
   4209    <TBD>.
   4210 
   4211    RETURN VALUE
   4212    OMX Error None if successful.
   4213    ========================================================================== */
   4214 OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
   4215         OMX_IN OMX_INDEXTYPE configIndex,
   4216         OMX_IN OMX_PTR        configData)
   4217 {
   4218     (void) hComp;
   4219     if (m_state == OMX_StateInvalid) {
   4220         DEBUG_PRINT_ERROR("Get Config in Invalid State");
   4221         return OMX_ErrorInvalidState;
   4222     }
   4223 
   4224     OMX_ERRORTYPE ret = OMX_ErrorNone;
   4225     OMX_VIDEO_CONFIG_NALSIZE *pNal;
   4226 
   4227     DEBUG_PRINT_LOW("Set Config Called");
   4228 
   4229     if (configIndex == (OMX_INDEXTYPE)OMX_IndexVendorVideoExtraData) {
   4230         OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
   4231         DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
   4232         if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc") ||
   4233             !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc")) {
   4234             DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
   4235             OMX_U32 extra_size;
   4236             // Parsing done here for the AVC atom is definitely not generic
   4237             // Currently this piece of code is working, but certainly
   4238             // not tested with all .mp4 files.
   4239             // Incase of failure, we might need to revisit this
   4240             // for a generic piece of code.
   4241 
   4242             // Retrieve size of NAL length field
   4243             // byte #4 contains the size of NAL lenght field
   4244             nal_length = (config->pData[4] & 0x03) + 1;
   4245 
   4246             extra_size = 0;
   4247             if (nal_length > 2) {
   4248                 /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
   4249                 extra_size = (nal_length - 2) * 2;
   4250             }
   4251 
   4252             // SPS starts from byte #6
   4253             OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
   4254             OMX_U8 *pDestBuf;
   4255             m_vendor_config.nPortIndex = config->nPortIndex;
   4256 
   4257             // minus 6 --> SPS starts from byte #6
   4258             // minus 1 --> picture param set byte to be ignored from avcatom
   4259             m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
   4260             m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
   4261             OMX_U32 len;
   4262             OMX_U8 index = 0;
   4263             // case where SPS+PPS is sent as part of set_config
   4264             pDestBuf = m_vendor_config.pData;
   4265 
   4266             DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%u] len[%u] data[%p]",
   4267                     (unsigned int)m_vendor_config.nPortIndex,
   4268                     (unsigned int)m_vendor_config.nDataSize,
   4269                     m_vendor_config.pData);
   4270             while (index < 2) {
   4271                 uint8 *psize;
   4272                 len = *pSrcBuf;
   4273                 len = len << 8;
   4274                 len |= *(pSrcBuf + 1);
   4275                 psize = (uint8 *) & len;
   4276                 memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
   4277                 for (unsigned int i = 0; i < nal_length; i++) {
   4278                     pDestBuf[i] = psize[nal_length - 1 - i];
   4279                 }
   4280                 //memcpy(pDestBuf,pSrcBuf,(len+2));
   4281                 pDestBuf += len + nal_length;
   4282                 pSrcBuf += len + 2;
   4283                 index++;
   4284                 pSrcBuf++;   // skip picture param set
   4285                 len = 0;
   4286             }
   4287         } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
   4288                 !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
   4289             m_vendor_config.nPortIndex = config->nPortIndex;
   4290             m_vendor_config.nDataSize = config->nDataSize;
   4291             m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
   4292             memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
   4293         } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
   4294             if (m_vendor_config.pData) {
   4295                 free(m_vendor_config.pData);
   4296                 m_vendor_config.pData = NULL;
   4297                 m_vendor_config.nDataSize = 0;
   4298             }
   4299 
   4300             if (((*((OMX_U32 *) config->pData)) &
   4301                         VC1_SP_MP_START_CODE_MASK) ==
   4302                     VC1_SP_MP_START_CODE) {
   4303                 DEBUG_PRINT_LOW("set_config - VC1 simple/main profile");
   4304                 m_vendor_config.nPortIndex = config->nPortIndex;
   4305                 m_vendor_config.nDataSize = config->nDataSize;
   4306                 m_vendor_config.pData =
   4307                     (OMX_U8 *) malloc(config->nDataSize);
   4308                 memcpy(m_vendor_config.pData, config->pData,
   4309                         config->nDataSize);
   4310                 m_vc1_profile = VC1_SP_MP_RCV;
   4311             } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
   4312                 DEBUG_PRINT_LOW("set_config - VC1 Advance profile");
   4313                 m_vendor_config.nPortIndex = config->nPortIndex;
   4314                 m_vendor_config.nDataSize = config->nDataSize;
   4315                 m_vendor_config.pData =
   4316                     (OMX_U8 *) malloc((config->nDataSize));
   4317                 memcpy(m_vendor_config.pData, config->pData,
   4318                         config->nDataSize);
   4319                 m_vc1_profile = VC1_AP;
   4320             } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
   4321                 DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only");
   4322                 m_vendor_config.nPortIndex = config->nPortIndex;
   4323                 m_vendor_config.nDataSize  = config->nDataSize;
   4324                 m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
   4325                 memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
   4326                 m_vc1_profile = VC1_SP_MP_RCV;
   4327             } else {
   4328                 DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile");
   4329             }
   4330         }
   4331         return ret;
   4332     } else if (configIndex == OMX_IndexConfigVideoNalSize) {
   4333         struct v4l2_control temp;
   4334         temp.id = V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT;
   4335 
   4336         pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
   4337         switch (pNal->nNaluBytes) {
   4338             case 0:
   4339                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_STARTCODES;
   4340                 break;
   4341             case 2:
   4342                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_TWO_BYTE_LENGTH;
   4343                 break;
   4344             case 4:
   4345                 temp.value = V4L2_MPEG_VIDC_VIDEO_NAL_FORMAT_FOUR_BYTE_LENGTH;
   4346                 break;
   4347             default:
   4348                 return OMX_ErrorUnsupportedSetting;
   4349         }
   4350 
   4351         if (!arbitrary_bytes) {
   4352             /* In arbitrary bytes mode, the assembler strips out nal size and replaces
   4353              * with start code, so only need to notify driver in frame by frame mode */
   4354             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &temp)) {
   4355                 DEBUG_PRINT_ERROR("Failed to set V4L2_CID_MPEG_VIDC_VIDEO_STREAM_FORMAT");
   4356                 return OMX_ErrorHardware;
   4357             }
   4358         }
   4359 
   4360         nal_length = pNal->nNaluBytes;
   4361         m_frame_parser.init_nal_length(nal_length);
   4362 
   4363         DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d", nal_length);
   4364         return ret;
   4365     } else if ((int)configIndex == (int)OMX_IndexVendorVideoFrameRate) {
   4366         OMX_VENDOR_VIDEOFRAMERATE *config = (OMX_VENDOR_VIDEOFRAMERATE *) configData;
   4367         DEBUG_PRINT_HIGH("Index OMX_IndexVendorVideoFrameRate %u", (unsigned int)config->nFps);
   4368 
   4369         if (config->nPortIndex == OMX_CORE_INPUT_PORT_INDEX) {
   4370             if (config->bEnabled) {
   4371                 if ((config->nFps >> 16) > 0) {
   4372                     DEBUG_PRINT_HIGH("set_config: frame rate set by omx client : %u",
   4373                             (unsigned int)config->nFps >> 16);
   4374                     Q16ToFraction(config->nFps, drv_ctx.frame_rate.fps_numerator,
   4375                             drv_ctx.frame_rate.fps_denominator);
   4376 
   4377                     if (!drv_ctx.frame_rate.fps_numerator) {
   4378                         DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
   4379                         drv_ctx.frame_rate.fps_numerator = 30;
   4380                     }
   4381 
   4382                     if (drv_ctx.frame_rate.fps_denominator) {
   4383                         drv_ctx.frame_rate.fps_numerator = (int)
   4384                             drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
   4385                     }
   4386 
   4387                     drv_ctx.frame_rate.fps_denominator = 1;
   4388                     frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
   4389                         drv_ctx.frame_rate.fps_numerator;
   4390 
   4391                     struct v4l2_outputparm oparm;
   4392                     /*XXX: we're providing timing info as seconds per frame rather than frames
   4393                      * per second.*/
   4394                     oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   4395                     oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   4396 
   4397                     struct v4l2_streamparm sparm;
   4398                     sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   4399                     sparm.parm.output = oparm;
   4400                     if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   4401                         DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   4402                                 performance might be affected");
   4403                         ret = OMX_ErrorHardware;
   4404                     }
   4405                     client_set_fps = true;
   4406                 } else {
   4407                     DEBUG_PRINT_ERROR("Frame rate not supported.");
   4408                     ret = OMX_ErrorUnsupportedSetting;
   4409                 }
   4410             } else {
   4411                 DEBUG_PRINT_HIGH("set_config: Disabled client's frame rate");
   4412                 client_set_fps = false;
   4413             }
   4414         } else {
   4415             DEBUG_PRINT_ERROR(" Set_config: Bad Port idx %d",
   4416                     (int)config->nPortIndex);
   4417             ret = OMX_ErrorBadPortIndex;
   4418         }
   4419 
   4420         return ret;
   4421     } else if ((int)configIndex == (int)OMX_QcomIndexConfigPerfLevel) {
   4422         OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *perf =
   4423             (OMX_QCOM_VIDEO_CONFIG_PERF_LEVEL *)configData;
   4424         struct v4l2_control control;
   4425 
   4426         DEBUG_PRINT_LOW("Set perf level: %d", perf->ePerfLevel);
   4427 
   4428         control.id = V4L2_CID_MPEG_VIDC_SET_PERF_LEVEL;
   4429 
   4430         switch (perf->ePerfLevel) {
   4431             case OMX_QCOM_PerfLevelNominal:
   4432                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_NOMINAL;
   4433                 break;
   4434             case OMX_QCOM_PerfLevelTurbo:
   4435                 control.value = V4L2_CID_MPEG_VIDC_PERF_LEVEL_TURBO;
   4436                 break;
   4437             default:
   4438                 ret = OMX_ErrorUnsupportedSetting;
   4439                 break;
   4440         }
   4441 
   4442         if (ret == OMX_ErrorNone) {
   4443             ret = (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control) < 0) ?
   4444                 OMX_ErrorUnsupportedSetting : OMX_ErrorNone;
   4445         }
   4446 
   4447         return ret;
   4448     } else if ((int)configIndex == (int)OMX_IndexConfigPriority) {
   4449         OMX_PARAM_U32TYPE *priority = (OMX_PARAM_U32TYPE *)configData;
   4450         DEBUG_PRINT_LOW("Set_config: priority %d", priority->nU32);
   4451 
   4452         struct v4l2_control control;
   4453 
   4454         control.id = V4L2_CID_MPEG_VIDC_VIDEO_PRIORITY;
   4455         if (priority->nU32 == 0)
   4456             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_ENABLE;
   4457         else
   4458             control.value = V4L2_MPEG_VIDC_VIDEO_PRIORITY_REALTIME_DISABLE;
   4459 
   4460         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   4461             DEBUG_PRINT_ERROR("Failed to set Priority");
   4462             ret = OMX_ErrorUnsupportedSetting;
   4463         }
   4464         return ret;
   4465     } else if ((int)configIndex == (int)OMX_IndexConfigOperatingRate) {
   4466         OMX_PARAM_U32TYPE *rate = (OMX_PARAM_U32TYPE *)configData;
   4467         DEBUG_PRINT_LOW("Set_config: operating-rate %u fps", rate->nU32 >> 16);
   4468 
   4469         struct v4l2_control control;
   4470 
   4471         control.id = V4L2_CID_MPEG_VIDC_VIDEO_OPERATING_RATE;
   4472         control.value = rate->nU32;
   4473 
   4474         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   4475             ret = errno == -EBUSY ? OMX_ErrorInsufficientResources :
   4476                     OMX_ErrorUnsupportedSetting;
   4477             DEBUG_PRINT_ERROR("Failed to set operating rate %u fps (%s)",
   4478                     rate->nU32 >> 16, errno == -EBUSY ? "HW Overload" : strerror(errno));
   4479         }
   4480         return ret;
   4481     }
   4482 
   4483     return OMX_ErrorNotImplemented;
   4484 }
   4485 
   4486 #define extn_equals(param, extn) (!strncmp(param, extn, strlen(extn)))
   4487 
   4488 /* ======================================================================
   4489    FUNCTION
   4490    omx_vdec::GetExtensionIndex
   4491 
   4492    DESCRIPTION
   4493    OMX GetExtensionIndex method implementaion.  <TBD>
   4494 
   4495    PARAMETERS
   4496    <TBD>.
   4497 
   4498    RETURN VALUE
   4499    OMX Error None if everything successful.
   4500 
   4501    ========================================================================== */
   4502 OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
   4503         OMX_IN OMX_STRING      paramName,
   4504         OMX_OUT OMX_INDEXTYPE* indexType)
   4505 {
   4506     (void) hComp;
   4507     if (m_state == OMX_StateInvalid) {
   4508         DEBUG_PRINT_ERROR("Get Extension Index in Invalid State");
   4509         return OMX_ErrorInvalidState;
   4510     } else if (extn_equals(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode")) {
   4511         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
   4512     } else if (extn_equals(paramName, "OMX.QCOM.index.param.IndexExtraData")) {
   4513         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
   4514     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_FRAMEPACKING_EXTRADATA)) {
   4515         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoFramePackingExtradata;
   4516     } else if (extn_equals(paramName, OMX_QCOM_INDEX_CONFIG_VIDEO_FRAMEPACKING_INFO)) {
   4517         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexConfigVideoFramePackingArrangement;
   4518     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_QP_EXTRADATA)) {
   4519         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoQPExtraData;
   4520     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_INPUTBITSINFO_EXTRADATA)) {
   4521         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoInputBitsInfoExtraData;
   4522     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_EXTNUSER_EXTRADATA)) {
   4523         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableExtnUserData;
   4524     } else if (extn_equals(paramName, OMX_QCOM_INDEX_PARAM_VIDEO_MPEG2SEQDISP_EXTRADATA)) {
   4525         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamMpeg2SeqDispExtraData;
   4526     }
   4527 #if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
   4528     else if (extn_equals(paramName, "OMX.google.android.index.enableAndroidNativeBuffers")) {
   4529         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
   4530     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer2")) {
   4531         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
   4532     } else if (extn_equals(paramName, "OMX.google.android.index.useAndroidNativeBuffer")) {
   4533         DEBUG_PRINT_ERROR("Extension: %s is supported", paramName);
   4534         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
   4535     } else if (extn_equals(paramName, "OMX.google.android.index.getAndroidNativeBufferUsage")) {
   4536         *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
   4537     }
   4538 #endif
   4539     else if (extn_equals(paramName, "OMX.google.android.index.storeMetaDataInBuffers")) {
   4540         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
   4541     }
   4542 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   4543     else if (extn_equals(paramName, "OMX.google.android.index.prepareForAdaptivePlayback")) {
   4544         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoAdaptivePlaybackMode;
   4545     }
   4546 #endif
   4547 #ifdef FLEXYUV_SUPPORTED
   4548     else if (extn_equals(paramName,"OMX.google.android.index.describeColorFormat")) {
   4549         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexFlexibleYUVDescription;
   4550     }
   4551 #endif
   4552     else {
   4553         DEBUG_PRINT_ERROR("Extension: %s not implemented", paramName);
   4554         return OMX_ErrorNotImplemented;
   4555     }
   4556     return OMX_ErrorNone;
   4557 }
   4558 
   4559 /* ======================================================================
   4560    FUNCTION
   4561    omx_vdec::GetState
   4562 
   4563    DESCRIPTION
   4564    Returns the state information back to the caller.<TBD>
   4565 
   4566    PARAMETERS
   4567    <TBD>.
   4568 
   4569    RETURN VALUE
   4570    Error None if everything is successful.
   4571    ========================================================================== */
   4572 OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
   4573         OMX_OUT OMX_STATETYPE* state)
   4574 {
   4575     (void) hComp;
   4576     *state = m_state;
   4577     DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
   4578     return OMX_ErrorNone;
   4579 }
   4580 
   4581 /* ======================================================================
   4582    FUNCTION
   4583    omx_vdec::ComponentTunnelRequest
   4584 
   4585    DESCRIPTION
   4586    OMX Component Tunnel Request method implementation. <TBD>
   4587 
   4588    PARAMETERS
   4589    None.
   4590 
   4591    RETURN VALUE
   4592    OMX Error None if everything successful.
   4593 
   4594    ========================================================================== */
   4595 OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE  hComp,
   4596         OMX_IN OMX_U32                        port,
   4597         OMX_IN OMX_HANDLETYPE        peerComponent,
   4598         OMX_IN OMX_U32                    peerPort,
   4599         OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
   4600 {
   4601     (void) hComp;
   4602     (void) port;
   4603     (void) peerComponent;
   4604     (void) peerPort;
   4605     (void) tunnelSetup;
   4606     DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented");
   4607     return OMX_ErrorNotImplemented;
   4608 }
   4609 
   4610 /* ======================================================================
   4611    FUNCTION
   4612    omx_vdec::UseOutputBuffer
   4613 
   4614    DESCRIPTION
   4615    Helper function for Use buffer in the input pin
   4616 
   4617    PARAMETERS
   4618    None.
   4619 
   4620    RETURN VALUE
   4621    true/false
   4622 
   4623    ========================================================================== */
   4624 OMX_ERRORTYPE omx_vdec::allocate_extradata()
   4625 {
   4626 #ifdef USE_ION
   4627     if (drv_ctx.extradata_info.buffer_size) {
   4628         if (drv_ctx.extradata_info.ion.ion_alloc_data.handle) {
   4629             munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   4630             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   4631             free_ion_memory(&drv_ctx.extradata_info.ion);
   4632         }
   4633         drv_ctx.extradata_info.size = (drv_ctx.extradata_info.size + 4095) & (~4095);
   4634         drv_ctx.extradata_info.ion.ion_device_fd = alloc_map_ion_memory(
   4635                 drv_ctx.extradata_info.size, 4096,
   4636                 &drv_ctx.extradata_info.ion.ion_alloc_data,
   4637                 &drv_ctx.extradata_info.ion.fd_ion_data, 0);
   4638         if (drv_ctx.extradata_info.ion.ion_device_fd < 0) {
   4639             DEBUG_PRINT_ERROR("Failed to alloc extradata memory");
   4640             return OMX_ErrorInsufficientResources;
   4641         }
   4642         drv_ctx.extradata_info.uaddr = (char *)mmap(NULL,
   4643                 drv_ctx.extradata_info.size,
   4644                 PROT_READ|PROT_WRITE, MAP_SHARED,
   4645                 drv_ctx.extradata_info.ion.fd_ion_data.fd , 0);
   4646         if (drv_ctx.extradata_info.uaddr == MAP_FAILED) {
   4647             DEBUG_PRINT_ERROR("Failed to map extradata memory");
   4648             close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   4649             free_ion_memory(&drv_ctx.extradata_info.ion);
   4650             return OMX_ErrorInsufficientResources;
   4651         }
   4652     }
   4653 #endif
   4654     if (!m_other_extradata) {
   4655         m_other_extradata = (OMX_OTHER_EXTRADATATYPE *)malloc(drv_ctx.extradata_info.buffer_size);
   4656         if (!m_other_extradata) {
   4657             DEBUG_PRINT_ERROR("Failed to alloc memory\n");
   4658             return OMX_ErrorInsufficientResources;
   4659         }
   4660     }
   4661     return OMX_ErrorNone;
   4662 }
   4663 
   4664 void omx_vdec::free_extradata()
   4665 {
   4666 #ifdef USE_ION
   4667     if (drv_ctx.extradata_info.uaddr) {
   4668         munmap((void *)drv_ctx.extradata_info.uaddr, drv_ctx.extradata_info.size);
   4669         close(drv_ctx.extradata_info.ion.fd_ion_data.fd);
   4670         free_ion_memory(&drv_ctx.extradata_info.ion);
   4671     }
   4672     memset(&drv_ctx.extradata_info, 0, sizeof(drv_ctx.extradata_info));
   4673 #endif
   4674     if (m_other_extradata) {
   4675         free(m_other_extradata);
   4676         m_other_extradata = NULL;
   4677     }
   4678 }
   4679 
   4680 OMX_ERRORTYPE  omx_vdec::use_output_buffer(
   4681         OMX_IN OMX_HANDLETYPE            hComp,
   4682         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4683         OMX_IN OMX_U32                   port,
   4684         OMX_IN OMX_PTR                   appData,
   4685         OMX_IN OMX_U32                   bytes,
   4686         OMX_IN OMX_U8*                   buffer)
   4687 {
   4688     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4689     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   4690     unsigned                         i= 0; // Temporary counter
   4691     struct vdec_setbuffer_cmd setbuffers;
   4692     OMX_PTR privateAppData = NULL;
   4693     private_handle_t *handle = NULL;
   4694     OMX_U8 *buff = buffer;
   4695     struct v4l2_buffer buf;
   4696     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   4697     int extra_idx = 0;
   4698     (void) hComp;
   4699     (void) port;
   4700 
   4701     if (!m_out_mem_ptr) {
   4702         DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
   4703         eRet = allocate_output_headers();
   4704         if (eRet == OMX_ErrorNone)
   4705             eRet = allocate_extradata();
   4706     }
   4707 
   4708     if (eRet == OMX_ErrorNone) {
   4709         for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   4710             if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   4711                 break;
   4712             }
   4713         }
   4714     }
   4715 
   4716     if (i >= drv_ctx.op_buf.actualcount) {
   4717         DEBUG_PRINT_ERROR("Already using %d o/p buffers", drv_ctx.op_buf.actualcount);
   4718         eRet = OMX_ErrorInsufficientResources;
   4719     }
   4720 
   4721     if (eRet != OMX_ErrorNone)
   4722        return eRet;
   4723 
   4724     if (dynamic_buf_mode) {
   4725         *bufferHdr = (m_out_mem_ptr + i );
   4726         (*bufferHdr)->pBuffer = NULL;
   4727         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   4728             enum v4l2_buf_type buf_type;
   4729             int rr = 0;
   4730             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4731             if (rr = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   4732                 DEBUG_PRINT_ERROR(" STREAMON FAILED : %d",rr);
   4733                 return OMX_ErrorInsufficientResources;
   4734             } else {
   4735                 streaming[CAPTURE_PORT] = true;
   4736                 DEBUG_PRINT_LOW("STREAMON Successful");
   4737             }
   4738         }
   4739         BITMASK_SET(&m_out_bm_count,i);
   4740         (*bufferHdr)->pAppPrivate = appData;
   4741         (*bufferHdr)->pBuffer = buffer;
   4742         (*bufferHdr)->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   4743         return eRet;
   4744     }
   4745 
   4746     if (eRet == OMX_ErrorNone) {
   4747 #if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
   4748         if (m_enable_android_native_buffers) {
   4749             if (m_use_android_native_buffers) {
   4750                 UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
   4751                 sp<android_native_buffer_t> nBuf = params->nativeBuffer;
   4752                 handle = (private_handle_t *)nBuf->handle;
   4753                 privateAppData = params->pAppPrivate;
   4754             } else {
   4755                 handle = (private_handle_t *)buff;
   4756                 privateAppData = appData;
   4757             }
   4758             if (!handle) {
   4759                 DEBUG_PRINT_ERROR("handle is invalid");
   4760                 return OMX_ErrorBadParameter;
   4761             }
   4762 
   4763             if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
   4764                 if (secure_mode && secure_scaling_to_non_secure_opb) {
   4765                     DEBUG_PRINT_HIGH("Buffer size expected %u, got %u, but it's ok since we will never map it",
   4766                         (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   4767                 } else {
   4768                 DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
   4769                         " expected %u, got %u",
   4770                             (unsigned int)drv_ctx.op_buf.buffer_size, (unsigned int)handle->size);
   4771                 return OMX_ErrorBadParameter;
   4772             }
   4773             }
   4774 
   4775             drv_ctx.op_buf.buffer_size = handle->size;
   4776 
   4777             if (!m_use_android_native_buffers) {
   4778                 if (!secure_mode) {
   4779                     buff =  (OMX_U8*)mmap(0, handle->size,
   4780                             PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
   4781                     if (buff == MAP_FAILED) {
   4782                         DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
   4783                         return OMX_ErrorInsufficientResources;
   4784                     }
   4785                 }
   4786             }
   4787 #if defined(_ANDROID_ICS_)
   4788             native_buffer[i].nativehandle = handle;
   4789             native_buffer[i].privatehandle = handle;
   4790 #endif
   4791             if (!handle) {
   4792                 DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
   4793                 return OMX_ErrorBadParameter;
   4794             }
   4795             drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
   4796             drv_ctx.ptr_outputbuffer[i].offset = 0;
   4797             drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   4798             drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   4799             drv_ctx.ptr_outputbuffer[i].mmaped_size = handle->size;
   4800         } else
   4801 #endif
   4802 
   4803             if (!ouput_egl_buffers && !m_use_output_pmem) {
   4804 #ifdef USE_ION
   4805                 drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   4806                         drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
   4807                         &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
   4808                         &drv_ctx.op_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE : 0);
   4809                 if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
   4810                     DEBUG_PRINT_ERROR("ION device fd is bad %d", drv_ctx.op_buf_ion_info[i].ion_device_fd);
   4811                     return OMX_ErrorInsufficientResources;
   4812                 }
   4813                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   4814                                       drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   4815 #else
   4816                 drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   4817                                       open (MEM_DEVICE,O_RDWR);
   4818 
   4819                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   4820                     DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4821                     return OMX_ErrorInsufficientResources;
   4822                 }
   4823 
   4824                 /* FIXME: why is this code even here? We already open MEM_DEVICE a few lines above */
   4825                 if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
   4826                     drv_ctx.ptr_outputbuffer[i].pmem_fd = \
   4827                                           open (MEM_DEVICE,O_RDWR);
   4828                     if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
   4829                         DEBUG_PRINT_ERROR("ION/pmem buffer fd is bad %d", drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4830                         return OMX_ErrorInsufficientResources;
   4831                     }
   4832                 }
   4833 
   4834                 if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
   4835                             drv_ctx.op_buf.buffer_size,
   4836                             drv_ctx.op_buf.alignment)) {
   4837                     DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   4838                     close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4839                     return OMX_ErrorInsufficientResources;
   4840                 }
   4841 #endif
   4842                 if (!secure_mode) {
   4843                     drv_ctx.ptr_outputbuffer[i].bufferaddr =
   4844                         (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
   4845                                 PROT_READ|PROT_WRITE, MAP_SHARED,
   4846                                 drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
   4847                     if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
   4848                         close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
   4849 #ifdef USE_ION
   4850                         free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   4851 #endif
   4852                         DEBUG_PRINT_ERROR("Unable to mmap output buffer");
   4853                         return OMX_ErrorInsufficientResources;
   4854                     }
   4855                 }
   4856                 drv_ctx.ptr_outputbuffer[i].offset = 0;
   4857                 privateAppData = appData;
   4858             } else {
   4859 
   4860                 DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
   4861                 if (!appData || !bytes ) {
   4862                     if (!secure_mode && !buffer) {
   4863                         DEBUG_PRINT_ERROR("Bad parameters for use buffer in EGL image case");
   4864                         return OMX_ErrorBadParameter;
   4865                     }
   4866                 }
   4867 
   4868                 OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
   4869                 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
   4870                 pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
   4871                 if (!pmem_list || !pmem_list->entryList || !pmem_list->entryList->entry ||
   4872                         !pmem_list->nEntries ||
   4873                         pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
   4874                     DEBUG_PRINT_ERROR("Pmem info not valid in use buffer");
   4875                     return OMX_ErrorBadParameter;
   4876                 }
   4877                 pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   4878                     pmem_list->entryList->entry;
   4879                 DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%lx",
   4880                         pmem_info->pmem_fd);
   4881                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
   4882                 drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
   4883                 drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
   4884                 drv_ctx.ptr_outputbuffer[i].mmaped_size =
   4885                     drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
   4886                 privateAppData = appData;
   4887             }
   4888         m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   4889         m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   4890         m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   4891         m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   4892         m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   4893 
   4894         *bufferHdr = (m_out_mem_ptr + i );
   4895         if (secure_mode)
   4896             drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   4897         //setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   4898         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
   4899                 sizeof (vdec_bufferpayload));
   4900 
   4901         DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %p, pmem_fd=0x%x", i,
   4902                 drv_ctx.ptr_outputbuffer[i].bufferaddr,
   4903                 drv_ctx.ptr_outputbuffer[i].pmem_fd );
   4904 
   4905         buf.index = i;
   4906         buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4907         buf.memory = V4L2_MEMORY_USERPTR;
   4908         plane[0].length = drv_ctx.op_buf.buffer_size;
   4909         plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   4910             (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   4911         plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[i].pmem_fd;
   4912         plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   4913         plane[0].data_offset = 0;
   4914         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   4915         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   4916             plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   4917             plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   4918 #ifdef USE_ION
   4919             plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   4920 #endif
   4921             plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   4922             plane[extra_idx].data_offset = 0;
   4923         } else if  (extra_idx >= VIDEO_MAX_PLANES) {
   4924             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   4925             return OMX_ErrorBadParameter;
   4926         }
   4927         buf.m.planes = plane;
   4928         buf.length = drv_ctx.num_planes;
   4929 
   4930         if (ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf)) {
   4931             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   4932             /*TODO: How to handle this case */
   4933             return OMX_ErrorInsufficientResources;
   4934         }
   4935 
   4936         if (i == (drv_ctx.op_buf.actualcount -1) && !streaming[CAPTURE_PORT]) {
   4937             enum v4l2_buf_type buf_type;
   4938             buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   4939             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type)) {
   4940                 return OMX_ErrorInsufficientResources;
   4941             } else {
   4942                 streaming[CAPTURE_PORT] = true;
   4943                 DEBUG_PRINT_LOW("STREAMON Successful");
   4944             }
   4945         }
   4946 
   4947         (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
   4948         if (m_enable_android_native_buffers) {
   4949             DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
   4950             (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
   4951         } else {
   4952             (*bufferHdr)->pBuffer = buff;
   4953         }
   4954         (*bufferHdr)->pAppPrivate = privateAppData;
   4955         BITMASK_SET(&m_out_bm_count,i);
   4956     }
   4957     return eRet;
   4958 }
   4959 
   4960 /* ======================================================================
   4961    FUNCTION
   4962    omx_vdec::use_input_heap_buffers
   4963 
   4964    DESCRIPTION
   4965    OMX Use Buffer Heap allocation method implementation.
   4966 
   4967    PARAMETERS
   4968    <TBD>.
   4969 
   4970    RETURN VALUE
   4971    OMX Error None , if everything successful.
   4972 
   4973    ========================================================================== */
   4974 OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
   4975         OMX_IN OMX_HANDLETYPE            hComp,
   4976         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   4977         OMX_IN OMX_U32                   port,
   4978         OMX_IN OMX_PTR                   appData,
   4979         OMX_IN OMX_U32                   bytes,
   4980         OMX_IN OMX_U8*                   buffer)
   4981 {
   4982     DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
   4983     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   4984     if (!m_inp_heap_ptr)
   4985         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
   4986             calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   4987                     drv_ctx.ip_buf.actualcount);
   4988     if (!m_phdr_pmem_ptr)
   4989         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
   4990             calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   4991                     drv_ctx.ip_buf.actualcount);
   4992     if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
   4993         DEBUG_PRINT_ERROR("Insufficent memory");
   4994         eRet = OMX_ErrorInsufficientResources;
   4995     } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
   4996         input_use_buffer = true;
   4997         memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
   4998         m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
   4999         m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
   5000         m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
   5001         m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
   5002         m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
   5003         *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
   5004         eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
   5005         DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
   5006         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[m_in_alloc_cnt],
   5007                     (unsigned)NULL, (unsigned)NULL)) {
   5008             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   5009             return OMX_ErrorInsufficientResources;
   5010         }
   5011         m_in_alloc_cnt++;
   5012     } else {
   5013         DEBUG_PRINT_ERROR("All i/p buffers have been set!");
   5014         eRet = OMX_ErrorInsufficientResources;
   5015     }
   5016     return eRet;
   5017 }
   5018 
   5019 /* ======================================================================
   5020    FUNCTION
   5021    omx_vdec::UseBuffer
   5022 
   5023    DESCRIPTION
   5024    OMX Use Buffer method implementation.
   5025 
   5026    PARAMETERS
   5027    <TBD>.
   5028 
   5029    RETURN VALUE
   5030    OMX Error None , if everything successful.
   5031 
   5032    ========================================================================== */
   5033 OMX_ERRORTYPE  omx_vdec::use_buffer(
   5034         OMX_IN OMX_HANDLETYPE            hComp,
   5035         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5036         OMX_IN OMX_U32                   port,
   5037         OMX_IN OMX_PTR                   appData,
   5038         OMX_IN OMX_U32                   bytes,
   5039         OMX_IN OMX_U8*                   buffer)
   5040 {
   5041     OMX_ERRORTYPE error = OMX_ErrorNone;
   5042     struct vdec_setbuffer_cmd setbuffers;
   5043 
   5044     if (bufferHdr == NULL || bytes == 0 || (!secure_mode && buffer == NULL)) {
   5045             DEBUG_PRINT_ERROR("bad param 0x%p %u 0x%p",bufferHdr, (unsigned int)bytes, buffer);
   5046             return OMX_ErrorBadParameter;
   5047         }
   5048     if (m_state == OMX_StateInvalid) {
   5049         DEBUG_PRINT_ERROR("Use Buffer in Invalid State");
   5050         return OMX_ErrorInvalidState;
   5051     }
   5052     if (port == OMX_CORE_INPUT_PORT_INDEX)
   5053         error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
   5054     else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
   5055         error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
   5056     else {
   5057         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   5058         error = OMX_ErrorBadPortIndex;
   5059     }
   5060     DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", (unsigned int)port, *bufferHdr, error);
   5061     if (error == OMX_ErrorNone) {
   5062         if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   5063             // Send the callback now
   5064             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   5065             post_event(OMX_CommandStateSet,OMX_StateIdle,
   5066                     OMX_COMPONENT_GENERATE_EVENT);
   5067         }
   5068         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
   5069                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   5070             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5071             post_event(OMX_CommandPortEnable,
   5072                     OMX_CORE_INPUT_PORT_INDEX,
   5073                     OMX_COMPONENT_GENERATE_EVENT);
   5074         } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
   5075                 BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   5076             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5077             post_event(OMX_CommandPortEnable,
   5078                     OMX_CORE_OUTPUT_PORT_INDEX,
   5079                     OMX_COMPONENT_GENERATE_EVENT);
   5080         }
   5081     }
   5082     return error;
   5083 }
   5084 
   5085 OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
   5086         OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
   5087 {
   5088     if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
   5089         if (m_inp_heap_ptr[bufferindex].pBuffer)
   5090             free(m_inp_heap_ptr[bufferindex].pBuffer);
   5091         m_inp_heap_ptr[bufferindex].pBuffer = NULL;
   5092     }
   5093     if (pmem_bufferHdr)
   5094         free_input_buffer(pmem_bufferHdr);
   5095     return OMX_ErrorNone;
   5096 }
   5097 
   5098 OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   5099 {
   5100     unsigned int index = 0;
   5101     if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
   5102         return OMX_ErrorBadParameter;
   5103     }
   5104 
   5105     index = bufferHdr - m_inp_mem_ptr;
   5106     DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   5107 
   5108     if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
   5109         DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
   5110         if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
   5111             struct vdec_setbuffer_cmd setbuffers;
   5112             setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
   5113             memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
   5114                     sizeof (vdec_bufferpayload));
   5115             if (!secure_mode) {
   5116                 DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
   5117                         drv_ctx.ptr_inputbuffer[index].pmem_fd);
   5118                 DEBUG_PRINT_LOW("unmap the input buffer size=%u  address = %p",
   5119                         (unsigned int)drv_ctx.ptr_inputbuffer[index].mmaped_size,
   5120                         drv_ctx.ptr_inputbuffer[index].bufferaddr);
   5121                 munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
   5122                         drv_ctx.ptr_inputbuffer[index].mmaped_size);
   5123             }
   5124             close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
   5125             drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
   5126             if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
   5127                 free(m_desc_buffer_ptr[index].buf_addr);
   5128                 m_desc_buffer_ptr[index].buf_addr = NULL;
   5129                 m_desc_buffer_ptr[index].desc_data_size = 0;
   5130             }
   5131 #ifdef USE_ION
   5132             free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
   5133 #endif
   5134         }
   5135     }
   5136 
   5137     return OMX_ErrorNone;
   5138 }
   5139 
   5140 OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
   5141 {
   5142     unsigned int index = 0;
   5143 
   5144     if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
   5145         return OMX_ErrorBadParameter;
   5146     }
   5147 
   5148     index = bufferHdr - m_out_mem_ptr;
   5149     DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
   5150 
   5151     if (index < drv_ctx.op_buf.actualcount
   5152             && drv_ctx.ptr_outputbuffer) {
   5153         DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %p", index,
   5154                 drv_ctx.ptr_outputbuffer[index].bufferaddr);
   5155 
   5156         struct vdec_setbuffer_cmd setbuffers;
   5157         setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
   5158         memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
   5159                 sizeof (vdec_bufferpayload));
   5160 
   5161         if (!dynamic_buf_mode) {
   5162 #ifdef _ANDROID_
   5163             if (m_enable_android_native_buffers) {
   5164                 if (!secure_mode) {
   5165                     if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
   5166                         munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
   5167                                 drv_ctx.ptr_outputbuffer[index].mmaped_size);
   5168                     }
   5169                 }
   5170                 drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
   5171             } else {
   5172 #endif
   5173                 if (drv_ctx.ptr_outputbuffer[0].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
   5174                     if (!secure_mode) {
   5175                         DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
   5176                                 drv_ctx.ptr_outputbuffer[0].pmem_fd);
   5177                         DEBUG_PRINT_LOW("unmap the ouput buffer size=%u  address = %p",
   5178                                 (unsigned int)drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount,
   5179                                 drv_ctx.ptr_outputbuffer[0].bufferaddr);
   5180                         munmap (drv_ctx.ptr_outputbuffer[0].bufferaddr,
   5181                                 drv_ctx.ptr_outputbuffer[0].mmaped_size * drv_ctx.op_buf.actualcount);
   5182                     }
   5183                     close (drv_ctx.ptr_outputbuffer[0].pmem_fd);
   5184                     drv_ctx.ptr_outputbuffer[0].pmem_fd = -1;
   5185 #ifdef USE_ION
   5186                     free_ion_memory(&drv_ctx.op_buf_ion_info[0]);
   5187 #endif
   5188                 }
   5189 #ifdef _ANDROID_
   5190             }
   5191 #endif
   5192         } //!dynamic_buf_mode
   5193         if (release_output_done()) {
   5194             free_extradata();
   5195         }
   5196     }
   5197 
   5198     return OMX_ErrorNone;
   5199 
   5200 }
   5201 
   5202 OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
   5203         OMX_BUFFERHEADERTYPE **bufferHdr,
   5204         OMX_U32              port,
   5205         OMX_PTR              appData,
   5206         OMX_U32              bytes)
   5207 {
   5208     OMX_BUFFERHEADERTYPE *input = NULL;
   5209     unsigned char *buf_addr = NULL;
   5210     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5211     unsigned   i = 0;
   5212 
   5213     /* Sanity Check*/
   5214     if (bufferHdr == NULL) {
   5215         return OMX_ErrorBadParameter;
   5216     }
   5217 
   5218     if (m_inp_heap_ptr == NULL) {
   5219         m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
   5220                  calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
   5221                          drv_ctx.ip_buf.actualcount);
   5222         m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
   5223                   calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
   5224                           drv_ctx.ip_buf.actualcount);
   5225 
   5226         if (m_inp_heap_ptr == NULL || m_phdr_pmem_ptr == NULL) {
   5227             DEBUG_PRINT_ERROR("m_inp_heap_ptr or m_phdr_pmem_ptr Allocation failed ");
   5228             return OMX_ErrorInsufficientResources;
   5229         }
   5230     }
   5231 
   5232     /*Find a Free index*/
   5233     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   5234         if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
   5235             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   5236             break;
   5237         }
   5238     }
   5239 
   5240     if (i < drv_ctx.ip_buf.actualcount) {
   5241         buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
   5242 
   5243         if (buf_addr == NULL) {
   5244             return OMX_ErrorInsufficientResources;
   5245         }
   5246 
   5247         *bufferHdr = (m_inp_heap_ptr + i);
   5248         input = *bufferHdr;
   5249         BITMASK_SET(&m_heap_inp_bm_count,i);
   5250 
   5251         input->pBuffer           = (OMX_U8 *)buf_addr;
   5252         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   5253         input->nVersion.nVersion = OMX_SPEC_VERSION;
   5254         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   5255         input->pAppPrivate       = appData;
   5256         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   5257         DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
   5258         eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
   5259         DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr[i]);
   5260         /*Add the Buffers to freeq*/
   5261         if (!m_input_free_q.insert_entry((unsigned long)m_phdr_pmem_ptr[i],
   5262                     (unsigned)NULL, (unsigned)NULL)) {
   5263             DEBUG_PRINT_ERROR("ERROR:Free_q is full");
   5264             return OMX_ErrorInsufficientResources;
   5265         }
   5266     } else {
   5267         return OMX_ErrorBadParameter;
   5268     }
   5269 
   5270     return eRet;
   5271 
   5272 }
   5273 
   5274 
   5275 /* ======================================================================
   5276    FUNCTION
   5277    omx_vdec::AllocateInputBuffer
   5278 
   5279    DESCRIPTION
   5280    Helper function for allocate buffer in the input pin
   5281 
   5282    PARAMETERS
   5283    None.
   5284 
   5285    RETURN VALUE
   5286    true/false
   5287 
   5288    ========================================================================== */
   5289 OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
   5290         OMX_IN OMX_HANDLETYPE            hComp,
   5291         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5292         OMX_IN OMX_U32                   port,
   5293         OMX_IN OMX_PTR                   appData,
   5294         OMX_IN OMX_U32                   bytes)
   5295 {
   5296     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5297     struct vdec_setbuffer_cmd setbuffers;
   5298     OMX_BUFFERHEADERTYPE *input = NULL;
   5299     unsigned   i = 0;
   5300     unsigned char *buf_addr = NULL;
   5301     int pmem_fd = -1;
   5302 
   5303     (void) hComp;
   5304     (void) port;
   5305 
   5306 
   5307     if (bytes != drv_ctx.ip_buf.buffer_size) {
   5308         DEBUG_PRINT_LOW("Requested Size is wrong %u epected is %u",
   5309                 (unsigned int)bytes, (unsigned int)drv_ctx.ip_buf.buffer_size);
   5310         return OMX_ErrorBadParameter;
   5311     }
   5312 
   5313     if (!m_inp_mem_ptr) {
   5314         DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%u)",
   5315                 drv_ctx.ip_buf.actualcount,
   5316                 (unsigned int)drv_ctx.ip_buf.buffer_size);
   5317 
   5318         m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
   5319                 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
   5320 
   5321         if (m_inp_mem_ptr == NULL) {
   5322             return OMX_ErrorInsufficientResources;
   5323         }
   5324 
   5325         drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
   5326                       calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
   5327 
   5328         if (drv_ctx.ptr_inputbuffer == NULL) {
   5329             return OMX_ErrorInsufficientResources;
   5330         }
   5331 #ifdef USE_ION
   5332         drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
   5333                       calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
   5334 
   5335         if (drv_ctx.ip_buf_ion_info == NULL) {
   5336             return OMX_ErrorInsufficientResources;
   5337         }
   5338 #endif
   5339 
   5340         for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
   5341             drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
   5342 #ifdef USE_ION
   5343             drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
   5344 #endif
   5345         }
   5346     }
   5347 
   5348     for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
   5349         if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   5350             DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
   5351             break;
   5352         }
   5353     }
   5354 
   5355     if (i < drv_ctx.ip_buf.actualcount) {
   5356         struct v4l2_buffer buf;
   5357         struct v4l2_plane plane;
   5358         int rc;
   5359         DEBUG_PRINT_LOW("Allocate input Buffer");
   5360 #ifdef USE_ION
   5361         drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
   5362                 drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
   5363                 &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
   5364                 &drv_ctx.ip_buf_ion_info[i].fd_ion_data, secure_mode ? ION_SECURE
   5365 #ifndef DISABLE_INPUT_BUFFER_CACHE
   5366                     : ION_FLAG_CACHED
   5367 #else
   5368                     : 0
   5369 #endif
   5370                     );
   5371         if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
   5372             return OMX_ErrorInsufficientResources;
   5373         }
   5374         pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
   5375 #else
   5376         pmem_fd = open (MEM_DEVICE,O_RDWR);
   5377 
   5378         if (pmem_fd < 0) {
   5379             DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   5380             return OMX_ErrorInsufficientResources;
   5381         }
   5382 
   5383         if (pmem_fd == 0) {
   5384             pmem_fd = open (MEM_DEVICE,O_RDWR);
   5385 
   5386             if (pmem_fd < 0) {
   5387                 DEBUG_PRINT_ERROR("open failed for pmem/adsp for input buffer");
   5388                 return OMX_ErrorInsufficientResources;
   5389             }
   5390         }
   5391 
   5392         if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
   5393                     drv_ctx.ip_buf.alignment)) {
   5394             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   5395             close(pmem_fd);
   5396             return OMX_ErrorInsufficientResources;
   5397         }
   5398 #endif
   5399         if (!secure_mode) {
   5400             buf_addr = (unsigned char *)mmap(NULL,
   5401                     drv_ctx.ip_buf.buffer_size,
   5402                     PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
   5403 
   5404             if (buf_addr == MAP_FAILED) {
   5405                 close(pmem_fd);
   5406 #ifdef USE_ION
   5407                 free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
   5408 #endif
   5409                 DEBUG_PRINT_ERROR("Map Failed to allocate input buffer");
   5410                 return OMX_ErrorInsufficientResources;
   5411             }
   5412         }
   5413         *bufferHdr = (m_inp_mem_ptr + i);
   5414         if (secure_mode)
   5415             drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
   5416         else
   5417             drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
   5418         drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
   5419         drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
   5420         drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
   5421         drv_ctx.ptr_inputbuffer [i].offset = 0;
   5422 
   5423 
   5424         buf.index = i;
   5425         buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   5426         buf.memory = V4L2_MEMORY_USERPTR;
   5427         plane.bytesused = 0;
   5428         plane.length = drv_ctx.ptr_inputbuffer [i].mmaped_size;
   5429         plane.m.userptr = (unsigned long)drv_ctx.ptr_inputbuffer[i].bufferaddr;
   5430         plane.reserved[0] =drv_ctx.ptr_inputbuffer [i].pmem_fd;
   5431         plane.reserved[1] = 0;
   5432         plane.data_offset = drv_ctx.ptr_inputbuffer[i].offset;
   5433         buf.m.planes = &plane;
   5434         buf.length = 1;
   5435 
   5436         DEBUG_PRINT_LOW("Set the input Buffer Idx: %d Addr: %p", i,
   5437                 drv_ctx.ptr_inputbuffer[i].bufferaddr);
   5438 
   5439         rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   5440 
   5441         if (rc) {
   5442             DEBUG_PRINT_ERROR("Failed to prepare bufs");
   5443             /*TODO: How to handle this case */
   5444             return OMX_ErrorInsufficientResources;
   5445         }
   5446 
   5447         input = *bufferHdr;
   5448         BITMASK_SET(&m_inp_bm_count,i);
   5449         DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
   5450         if (secure_mode)
   5451             input->pBuffer = (OMX_U8 *)(intptr_t)drv_ctx.ptr_inputbuffer [i].pmem_fd;
   5452         else
   5453             input->pBuffer           = (OMX_U8 *)buf_addr;
   5454         input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
   5455         input->nVersion.nVersion = OMX_SPEC_VERSION;
   5456         input->nAllocLen         = drv_ctx.ip_buf.buffer_size;
   5457         input->pAppPrivate       = appData;
   5458         input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
   5459         input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
   5460 
   5461         if (drv_ctx.disable_dmx) {
   5462             eRet = allocate_desc_buffer(i);
   5463         }
   5464     } else {
   5465         DEBUG_PRINT_ERROR("ERROR:Input Buffer Index not found");
   5466         eRet = OMX_ErrorInsufficientResources;
   5467     }
   5468     return eRet;
   5469 }
   5470 
   5471 
   5472 /* ======================================================================
   5473    FUNCTION
   5474    omx_vdec::AllocateOutputBuffer
   5475 
   5476    DESCRIPTION
   5477    Helper fn for AllocateBuffer in the output pin
   5478 
   5479    PARAMETERS
   5480    <TBD>.
   5481 
   5482    RETURN VALUE
   5483    OMX Error None if everything went well.
   5484 
   5485    ========================================================================== */
   5486 OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
   5487         OMX_IN OMX_HANDLETYPE            hComp,
   5488         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5489         OMX_IN OMX_U32                   port,
   5490         OMX_IN OMX_PTR                   appData,
   5491         OMX_IN OMX_U32                   bytes)
   5492 {
   5493     (void)hComp;
   5494     (void)port;
   5495     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5496     OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
   5497     unsigned                         i= 0; // Temporary counter
   5498     struct vdec_setbuffer_cmd setbuffers;
   5499     int extra_idx = 0;
   5500 #ifdef USE_ION
   5501     int ion_device_fd =-1;
   5502     struct ion_allocation_data ion_alloc_data;
   5503     struct ion_fd_data fd_ion_data;
   5504 #endif
   5505     if (!m_out_mem_ptr) {
   5506         DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%u)",
   5507                 drv_ctx.op_buf.actualcount,
   5508                 (unsigned int)drv_ctx.op_buf.buffer_size);
   5509         int nBufHdrSize        = 0;
   5510         int nPlatformEntrySize = 0;
   5511         int nPlatformListSize  = 0;
   5512         int nPMEMInfoSize = 0;
   5513         int pmem_fd = -1;
   5514         unsigned char *pmem_baseaddress = NULL;
   5515 
   5516         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   5517         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   5518         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   5519 
   5520         DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
   5521                 drv_ctx.op_buf.actualcount);
   5522         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   5523             sizeof(OMX_BUFFERHEADERTYPE);
   5524 
   5525         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   5526             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   5527         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   5528             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   5529         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   5530             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   5531 
   5532         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   5533                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   5534                 nPMEMInfoSize,
   5535                 nPlatformListSize);
   5536         DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
   5537                 drv_ctx.op_buf.actualcount);
   5538 #ifdef USE_ION
   5539         // Allocate output buffers as cached to improve performance of software-reading
   5540         // of the YUVs. Output buffers are cache-invalidated in driver.
   5541         // If color-conversion is involved, Only the C2D output buffers are cached, no
   5542         // need to cache the decoder's output buffers
   5543         int cache_flag = client_buffers.is_color_conversion_enabled() ? 0 : ION_FLAG_CACHED;
   5544         ion_device_fd = alloc_map_ion_memory(
   5545                 drv_ctx.op_buf.buffer_size * drv_ctx.op_buf.actualcount,
   5546                 secure_scaling_to_non_secure_opb ? SZ_4K : drv_ctx.op_buf.alignment,
   5547                 &ion_alloc_data, &fd_ion_data,
   5548                 (secure_mode && !secure_scaling_to_non_secure_opb) ? ION_SECURE : cache_flag);
   5549         if (ion_device_fd < 0) {
   5550             return OMX_ErrorInsufficientResources;
   5551         }
   5552         pmem_fd = fd_ion_data.fd;
   5553 #else
   5554         pmem_fd = open (MEM_DEVICE,O_RDWR);
   5555 
   5556         if (pmem_fd < 0) {
   5557             DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   5558                     drv_ctx.op_buf.buffer_size);
   5559             return OMX_ErrorInsufficientResources;
   5560         }
   5561 
   5562         if (pmem_fd == 0) {
   5563             pmem_fd = open (MEM_DEVICE,O_RDWR);
   5564 
   5565             if (pmem_fd < 0) {
   5566                 DEBUG_PRINT_ERROR("ERROR:pmem fd for output buffer %d",
   5567                         drv_ctx.op_buf.buffer_size);
   5568                 return OMX_ErrorInsufficientResources;
   5569             }
   5570         }
   5571 
   5572         if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size *
   5573                     drv_ctx.op_buf.actualcount,
   5574                     drv_ctx.op_buf.alignment)) {
   5575             DEBUG_PRINT_ERROR("align_pmem_buffers() failed");
   5576             close(pmem_fd);
   5577             return OMX_ErrorInsufficientResources;
   5578         }
   5579 #endif
   5580         if (!secure_mode) {
   5581             pmem_baseaddress = (unsigned char *)mmap(NULL,
   5582                     (drv_ctx.op_buf.buffer_size *
   5583                      drv_ctx.op_buf.actualcount),
   5584                     PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
   5585             if (pmem_baseaddress == MAP_FAILED) {
   5586                 DEBUG_PRINT_ERROR("MMAP failed for Size %u",
   5587                         (unsigned int)drv_ctx.op_buf.buffer_size);
   5588                 close(pmem_fd);
   5589 #ifdef USE_ION
   5590                 free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
   5591 #endif
   5592                 return OMX_ErrorInsufficientResources;
   5593             }
   5594         }
   5595         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   5596         // Alloc mem for platform specific info
   5597         char *pPtr=NULL;
   5598         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   5599                 nPMEMInfoSize,1);
   5600         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
   5601                        calloc (sizeof(struct vdec_bufferpayload),
   5602                                drv_ctx.op_buf.actualcount);
   5603         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   5604                      calloc (sizeof (struct vdec_output_frameinfo),
   5605                              drv_ctx.op_buf.actualcount);
   5606         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   5607             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer ");
   5608             return OMX_ErrorInsufficientResources;
   5609         }
   5610 
   5611 #ifdef USE_ION
   5612         drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
   5613                       calloc (sizeof(struct vdec_ion),
   5614                               drv_ctx.op_buf.actualcount);
   5615         if (!drv_ctx.op_buf_ion_info) {
   5616             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   5617             return OMX_ErrorInsufficientResources;
   5618         }
   5619 #endif
   5620 
   5621         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   5622                 && drv_ctx.ptr_respbuffer) {
   5623             drv_ctx.ptr_outputbuffer[0].mmaped_size =
   5624                 (drv_ctx.op_buf.buffer_size *
   5625                  drv_ctx.op_buf.actualcount);
   5626             bufHdr          =  m_out_mem_ptr;
   5627             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   5628             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   5629                 (((char *) m_platform_list)  + nPlatformListSize);
   5630             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   5631                 (((char *) m_platform_entry) + nPlatformEntrySize);
   5632             pPlatformList   = m_platform_list;
   5633             pPlatformEntry  = m_platform_entry;
   5634             pPMEMInfo       = m_pmem_info;
   5635 
   5636             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   5637 
   5638             // Settting the entire storage nicely
   5639             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
   5640             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   5641             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   5642                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   5643                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   5644                 // Set the values when we determine the right HxW param
   5645                 bufHdr->nAllocLen          = bytes;
   5646                 bufHdr->nFilledLen         = 0;
   5647                 bufHdr->pAppPrivate        = appData;
   5648                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   5649                 // Platform specific PMEM Information
   5650                 // Initialize the Platform Entry
   5651                 //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
   5652                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   5653                 pPlatformEntry->entry      = pPMEMInfo;
   5654                 // Initialize the Platform List
   5655                 pPlatformList->nEntries    = 1;
   5656                 pPlatformList->entryList   = pPlatformEntry;
   5657                 // Keep pBuffer NULL till vdec is opened
   5658                 bufHdr->pBuffer            = NULL;
   5659                 bufHdr->nOffset            = 0;
   5660 
   5661                 pPMEMInfo->offset          =  drv_ctx.op_buf.buffer_size*i;
   5662                 pPMEMInfo->pmem_fd = 0;
   5663                 bufHdr->pPlatformPrivate = pPlatformList;
   5664 
   5665                 drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_fd;
   5666                 m_pmem_info[i].pmem_fd = pmem_fd;
   5667 #ifdef USE_ION
   5668                 drv_ctx.op_buf_ion_info[i].ion_device_fd = ion_device_fd;
   5669                 drv_ctx.op_buf_ion_info[i].ion_alloc_data = ion_alloc_data;
   5670                 drv_ctx.op_buf_ion_info[i].fd_ion_data = fd_ion_data;
   5671 #endif
   5672 
   5673                 /*Create a mapping between buffers*/
   5674                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   5675                 drv_ctx.ptr_respbuffer[i].client_data = (void *)\
   5676                                     &drv_ctx.ptr_outputbuffer[i];
   5677                 drv_ctx.ptr_outputbuffer[i].offset = drv_ctx.op_buf.buffer_size*i;
   5678                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   5679                     pmem_baseaddress + (drv_ctx.op_buf.buffer_size*i);
   5680                 m_pmem_info[i].size = drv_ctx.ptr_outputbuffer[i].buffer_len;
   5681                 m_pmem_info[i].mapped_size = drv_ctx.ptr_outputbuffer[i].mmaped_size;
   5682                 m_pmem_info[i].buffer = drv_ctx.ptr_outputbuffer[i].bufferaddr;
   5683 
   5684                 DEBUG_PRINT_LOW("pmem_fd = %d offset = %u address = %p",
   5685                         pmem_fd, (unsigned int)drv_ctx.ptr_outputbuffer[i].offset,
   5686                         drv_ctx.ptr_outputbuffer[i].bufferaddr);
   5687                 // Move the buffer and buffer header pointers
   5688                 bufHdr++;
   5689                 pPMEMInfo++;
   5690                 pPlatformEntry++;
   5691                 pPlatformList++;
   5692             }
   5693         } else {
   5694             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   5695                     m_out_mem_ptr, pPtr);
   5696             if (m_out_mem_ptr) {
   5697                 free(m_out_mem_ptr);
   5698                 m_out_mem_ptr = NULL;
   5699             }
   5700             if (pPtr) {
   5701                 free(pPtr);
   5702                 pPtr = NULL;
   5703             }
   5704             if (drv_ctx.ptr_outputbuffer) {
   5705                 free(drv_ctx.ptr_outputbuffer);
   5706                 drv_ctx.ptr_outputbuffer = NULL;
   5707             }
   5708             if (drv_ctx.ptr_respbuffer) {
   5709                 free(drv_ctx.ptr_respbuffer);
   5710                 drv_ctx.ptr_respbuffer = NULL;
   5711             }
   5712 #ifdef USE_ION
   5713             if (drv_ctx.op_buf_ion_info) {
   5714                 DEBUG_PRINT_LOW("Free o/p ion context");
   5715                 free(drv_ctx.op_buf_ion_info);
   5716                 drv_ctx.op_buf_ion_info = NULL;
   5717             }
   5718 #endif
   5719             eRet =  OMX_ErrorInsufficientResources;
   5720         }
   5721         if (eRet == OMX_ErrorNone)
   5722             eRet = allocate_extradata();
   5723     }
   5724 
   5725     for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
   5726         if (BITMASK_ABSENT(&m_out_bm_count,i)) {
   5727             DEBUG_PRINT_LOW("Found a Free Output Buffer %d",i);
   5728             break;
   5729         }
   5730     }
   5731 
   5732     if (eRet == OMX_ErrorNone) {
   5733         if (i < drv_ctx.op_buf.actualcount) {
   5734             struct v4l2_buffer buf;
   5735             struct v4l2_plane plane[VIDEO_MAX_PLANES];
   5736             int rc;
   5737             m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
   5738 
   5739             drv_ctx.ptr_outputbuffer[i].buffer_len =
   5740                 drv_ctx.op_buf.buffer_size;
   5741 
   5742             *bufferHdr = (m_out_mem_ptr + i );
   5743             if (secure_mode) {
   5744 #ifdef USE_ION
   5745                 drv_ctx.ptr_outputbuffer[i].bufferaddr =
   5746                     (OMX_U8 *)(intptr_t)drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   5747 #else
   5748                 drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
   5749 #endif
   5750             }
   5751             drv_ctx.ptr_outputbuffer[i].mmaped_size = drv_ctx.op_buf.buffer_size;
   5752 
   5753             buf.index = i;
   5754             buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5755             buf.memory = V4L2_MEMORY_USERPTR;
   5756             plane[0].length = drv_ctx.op_buf.buffer_size;
   5757             plane[0].m.userptr = (unsigned long)drv_ctx.ptr_outputbuffer[i].bufferaddr -
   5758                 (unsigned long)drv_ctx.ptr_outputbuffer[i].offset;
   5759 #ifdef USE_ION
   5760             plane[0].reserved[0] = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
   5761 #endif
   5762             plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[i].offset;
   5763             plane[0].data_offset = 0;
   5764             extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   5765             if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   5766                 plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   5767                 plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + i * drv_ctx.extradata_info.buffer_size);
   5768 #ifdef USE_ION
   5769                 plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   5770 #endif
   5771                 plane[extra_idx].reserved[1] = i * drv_ctx.extradata_info.buffer_size;
   5772                 plane[extra_idx].data_offset = 0;
   5773             } else if (extra_idx >= VIDEO_MAX_PLANES) {
   5774                 DEBUG_PRINT_ERROR("Extradata index higher than allowed: %d", extra_idx);
   5775                 return OMX_ErrorBadParameter;
   5776             }
   5777             buf.m.planes = plane;
   5778             buf.length = drv_ctx.num_planes;
   5779             DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %p", i, drv_ctx.ptr_outputbuffer[i].bufferaddr);
   5780             rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_PREPARE_BUF, &buf);
   5781             if (rc) {
   5782                 /*TODO: How to handle this case */
   5783                 return OMX_ErrorInsufficientResources;
   5784             }
   5785 
   5786             if (i == (drv_ctx.op_buf.actualcount -1 ) && !streaming[CAPTURE_PORT]) {
   5787                 enum v4l2_buf_type buf_type;
   5788                 buf_type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   5789                 rc=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   5790                 if (rc) {
   5791                     return OMX_ErrorInsufficientResources;
   5792                 } else {
   5793                     streaming[CAPTURE_PORT] = true;
   5794                     DEBUG_PRINT_LOW("STREAMON Successful");
   5795                 }
   5796             }
   5797 
   5798             (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
   5799             (*bufferHdr)->pAppPrivate = appData;
   5800             BITMASK_SET(&m_out_bm_count,i);
   5801         } else {
   5802             DEBUG_PRINT_ERROR("All the Output Buffers have been Allocated ; Returning Insufficient");
   5803             eRet = OMX_ErrorInsufficientResources;
   5804         }
   5805     }
   5806 
   5807     return eRet;
   5808 }
   5809 
   5810 
   5811 // AllocateBuffer  -- API Call
   5812 /* ======================================================================
   5813    FUNCTION
   5814    omx_vdec::AllocateBuffer
   5815 
   5816    DESCRIPTION
   5817    Returns zero if all the buffers released..
   5818 
   5819    PARAMETERS
   5820    None.
   5821 
   5822    RETURN VALUE
   5823    true/false
   5824 
   5825    ========================================================================== */
   5826 OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
   5827         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   5828         OMX_IN OMX_U32                        port,
   5829         OMX_IN OMX_PTR                     appData,
   5830         OMX_IN OMX_U32                       bytes)
   5831 {
   5832     unsigned i = 0;
   5833     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
   5834 
   5835     DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
   5836     if (m_state == OMX_StateInvalid) {
   5837         DEBUG_PRINT_ERROR("Allocate Buf in Invalid State");
   5838         return OMX_ErrorInvalidState;
   5839     }
   5840 
   5841     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   5842         if (arbitrary_bytes) {
   5843             eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
   5844         } else {
   5845             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
   5846         }
   5847     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   5848         eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
   5849                 appData,bytes);
   5850     } else {
   5851         DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d",(int)port);
   5852         eRet = OMX_ErrorBadPortIndex;
   5853     }
   5854     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
   5855     if (eRet == OMX_ErrorNone) {
   5856         if (allocate_done()) {
   5857             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
   5858                 // Send the callback now
   5859                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
   5860                 post_event(OMX_CommandStateSet,OMX_StateIdle,
   5861                         OMX_COMPONENT_GENERATE_EVENT);
   5862             }
   5863         }
   5864         if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
   5865             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
   5866                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
   5867                 post_event(OMX_CommandPortEnable,
   5868                         OMX_CORE_INPUT_PORT_INDEX,
   5869                         OMX_COMPONENT_GENERATE_EVENT);
   5870             }
   5871         }
   5872         if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
   5873             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
   5874                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
   5875                 post_event(OMX_CommandPortEnable,
   5876                         OMX_CORE_OUTPUT_PORT_INDEX,
   5877                         OMX_COMPONENT_GENERATE_EVENT);
   5878             }
   5879         }
   5880     }
   5881     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
   5882     return eRet;
   5883 }
   5884 
   5885 // Free Buffer - API call
   5886 /* ======================================================================
   5887    FUNCTION
   5888    omx_vdec::FreeBuffer
   5889 
   5890    DESCRIPTION
   5891 
   5892    PARAMETERS
   5893    None.
   5894 
   5895    RETURN VALUE
   5896    true/false
   5897 
   5898    ========================================================================== */
   5899 OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   5900         OMX_IN OMX_U32                 port,
   5901         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   5902 {
   5903     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   5904     unsigned int nPortIndex;
   5905     (void) hComp;
   5906     DEBUG_PRINT_LOW("In for decoder free_buffer");
   5907 
   5908     if (m_state == OMX_StateIdle &&
   5909             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   5910         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
   5911     } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
   5912             (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
   5913         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
   5914     } else if ((port == OMX_CORE_INPUT_PORT_INDEX &&
   5915                 BITMASK_PRESENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING)) ||
   5916             (port == OMX_CORE_OUTPUT_PORT_INDEX &&
   5917              BITMASK_PRESENT(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING))) {
   5918         DEBUG_PRINT_LOW("Free Buffer while port %u enable pending", (unsigned int)port);
   5919     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
   5920         DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled");
   5921         post_event(OMX_EventError,
   5922                 OMX_ErrorPortUnpopulated,
   5923                 OMX_COMPONENT_GENERATE_EVENT);
   5924 
   5925         return OMX_ErrorIncorrectStateOperation;
   5926     } else if (m_state != OMX_StateInvalid) {
   5927         DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers");
   5928         post_event(OMX_EventError,
   5929                 OMX_ErrorPortUnpopulated,
   5930                 OMX_COMPONENT_GENERATE_EVENT);
   5931     }
   5932 
   5933     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   5934         /*Check if arbitrary bytes*/
   5935         if (!arbitrary_bytes && !input_use_buffer)
   5936             nPortIndex = buffer - m_inp_mem_ptr;
   5937         else
   5938             nPortIndex = buffer - m_inp_heap_ptr;
   5939 
   5940         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
   5941         if (nPortIndex < drv_ctx.ip_buf.actualcount) {
   5942             // Clear the bit associated with it.
   5943             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
   5944             BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
   5945             if (input_use_buffer == true) {
   5946 
   5947                 DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
   5948                 if (m_phdr_pmem_ptr)
   5949                     free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
   5950             } else {
   5951                 if (arbitrary_bytes) {
   5952                     if (m_phdr_pmem_ptr)
   5953                         free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
   5954                     else
   5955                         free_input_buffer(nPortIndex,NULL);
   5956                 } else
   5957                     free_input_buffer(buffer);
   5958             }
   5959             m_inp_bPopulated = OMX_FALSE;
   5960             if(release_input_done())
   5961                 release_buffers(this, VDEC_BUFFER_TYPE_INPUT);
   5962             /*Free the Buffer Header*/
   5963             if (release_input_done()) {
   5964                 DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
   5965                 free_input_buffer_header();
   5966             }
   5967         } else {
   5968             DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid");
   5969             eRet = OMX_ErrorBadPortIndex;
   5970         }
   5971 
   5972         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
   5973                 && release_input_done()) {
   5974             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   5975             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
   5976             post_event(OMX_CommandPortDisable,
   5977                     OMX_CORE_INPUT_PORT_INDEX,
   5978                     OMX_COMPONENT_GENERATE_EVENT);
   5979         }
   5980     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   5981         // check if the buffer is valid
   5982         nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   5983         if (nPortIndex < drv_ctx.op_buf.actualcount) {
   5984             DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
   5985             // Clear the bit associated with it.
   5986             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
   5987             m_out_bPopulated = OMX_FALSE;
   5988             client_buffers.free_output_buffer (buffer);
   5989 
   5990             if(release_output_done()) {
   5991                 release_buffers(this, VDEC_BUFFER_TYPE_OUTPUT);
   5992             }
   5993             if (release_output_done()) {
   5994                 free_output_buffer_header();
   5995             }
   5996         } else {
   5997             DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid");
   5998             eRet = OMX_ErrorBadPortIndex;
   5999         }
   6000         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
   6001                 && release_output_done()) {
   6002             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
   6003 
   6004             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
   6005             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
   6006 #ifdef _ANDROID_ICS_
   6007             if (m_enable_android_native_buffers) {
   6008                 DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
   6009                 memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   6010             }
   6011 #endif
   6012 
   6013             post_event(OMX_CommandPortDisable,
   6014                     OMX_CORE_OUTPUT_PORT_INDEX,
   6015                     OMX_COMPONENT_GENERATE_EVENT);
   6016         }
   6017     } else {
   6018         eRet = OMX_ErrorBadPortIndex;
   6019     }
   6020     if ((eRet == OMX_ErrorNone) &&
   6021             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
   6022         if (release_done()) {
   6023             // Send the callback now
   6024             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
   6025             post_event(OMX_CommandStateSet, OMX_StateLoaded,
   6026                     OMX_COMPONENT_GENERATE_EVENT);
   6027         }
   6028     }
   6029     return eRet;
   6030 }
   6031 
   6032 
   6033 /* ======================================================================
   6034    FUNCTION
   6035    omx_vdec::EmptyThisBuffer
   6036 
   6037    DESCRIPTION
   6038    This routine is used to push the encoded video frames to
   6039    the video decoder.
   6040 
   6041    PARAMETERS
   6042    None.
   6043 
   6044    RETURN VALUE
   6045    OMX Error None if everything went successful.
   6046 
   6047    ========================================================================== */
   6048 OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
   6049         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6050 {
   6051     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
   6052     unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
   6053 
   6054     if (m_state == OMX_StateInvalid) {
   6055         DEBUG_PRINT_ERROR("Empty this buffer in Invalid State");
   6056         return OMX_ErrorInvalidState;
   6057     }
   6058 
   6059     if (buffer == NULL) {
   6060         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   6061         return OMX_ErrorBadParameter;
   6062     }
   6063 
   6064     if (!m_inp_bEnabled) {
   6065         DEBUG_PRINT_ERROR("ERROR:ETB incorrect state operation, input port is disabled.");
   6066         return OMX_ErrorIncorrectStateOperation;
   6067     }
   6068 
   6069     if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
   6070         DEBUG_PRINT_ERROR("ERROR:ETB invalid port in header %u", (unsigned int)buffer->nInputPortIndex);
   6071         return OMX_ErrorBadPortIndex;
   6072     }
   6073 
   6074 #ifdef _ANDROID_
   6075     if (iDivXDrmDecrypt) {
   6076         OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
   6077         if (drmErr != OMX_ErrorNone) {
   6078             // this error can be ignored
   6079             DEBUG_PRINT_LOW("ERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
   6080         }
   6081     }
   6082 #endif //_ANDROID_
   6083     if (perf_flag) {
   6084         if (!latency) {
   6085             dec_time.stop();
   6086             latency = dec_time.processing_time_us();
   6087             dec_time.start();
   6088         }
   6089     }
   6090 
   6091     if (arbitrary_bytes) {
   6092         nBufferIndex = buffer - m_inp_heap_ptr;
   6093     } else {
   6094         if (input_use_buffer == true) {
   6095             nBufferIndex = buffer - m_inp_heap_ptr;
   6096             m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
   6097             m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
   6098             m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
   6099             buffer = &m_inp_mem_ptr[nBufferIndex];
   6100             DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %u",
   6101                     &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, (unsigned int)buffer->nFilledLen);
   6102         } else {
   6103             nBufferIndex = buffer - m_inp_mem_ptr;
   6104         }
   6105     }
   6106 
   6107     if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
   6108         DEBUG_PRINT_ERROR("ERROR:ETB nBufferIndex is invalid");
   6109         return OMX_ErrorBadParameter;
   6110     }
   6111 
   6112     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   6113         codec_config_flag = true;
   6114         DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
   6115     }
   6116 
   6117     DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%u)",
   6118             buffer, buffer->pBuffer, buffer->nTimeStamp, (unsigned int)buffer->nFilledLen);
   6119     if (arbitrary_bytes) {
   6120         post_event ((unsigned long)hComp,(unsigned long)buffer,
   6121                 OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
   6122     } else {
   6123         post_event ((unsigned long)hComp,(unsigned long)buffer,OMX_COMPONENT_GENERATE_ETB);
   6124     }
   6125     time_stamp_dts.insert_timestamp(buffer);
   6126     return OMX_ErrorNone;
   6127 }
   6128 
   6129 /* ======================================================================
   6130    FUNCTION
   6131    omx_vdec::empty_this_buffer_proxy
   6132 
   6133    DESCRIPTION
   6134    This routine is used to push the encoded video frames to
   6135    the video decoder.
   6136 
   6137    PARAMETERS
   6138    None.
   6139 
   6140    RETURN VALUE
   6141    OMX Error None if everything went successful.
   6142 
   6143    ========================================================================== */
   6144 OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
   6145         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6146 {
   6147     (void) hComp;
   6148     int push_cnt = 0,i=0;
   6149     unsigned nPortIndex = 0;
   6150     OMX_ERRORTYPE ret = OMX_ErrorNone;
   6151     struct vdec_input_frameinfo frameinfo;
   6152     struct vdec_bufferpayload *temp_buffer;
   6153     struct vdec_seqheader seq_header;
   6154     bool port_setting_changed = true;
   6155 
   6156     /*Should we generate a Aync error event*/
   6157     if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
   6158         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy is invalid");
   6159         return OMX_ErrorBadParameter;
   6160     }
   6161 
   6162     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   6163 
   6164     if (nPortIndex > drv_ctx.ip_buf.actualcount) {
   6165         DEBUG_PRINT_ERROR("ERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
   6166                 nPortIndex);
   6167         return OMX_ErrorBadParameter;
   6168     }
   6169 
   6170     pending_input_buffers++;
   6171 
   6172     /* return zero length and not an EOS buffer */
   6173     if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
   6174             ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
   6175         DEBUG_PRINT_HIGH("return zero legth buffer");
   6176         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   6177                 OMX_COMPONENT_GENERATE_EBD);
   6178         return OMX_ErrorNone;
   6179     }
   6180 
   6181     if (input_flush_progress == true) {
   6182         DEBUG_PRINT_LOW("Flush in progress return buffer ");
   6183         post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   6184                 OMX_COMPONENT_GENERATE_EBD);
   6185         return OMX_ErrorNone;
   6186     }
   6187 
   6188     temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
   6189 
   6190     if ((temp_buffer -  drv_ctx.ptr_inputbuffer) > (int)drv_ctx.ip_buf.actualcount) {
   6191         return OMX_ErrorBadParameter;
   6192     }
   6193     /* If its first frame, H264 codec and reject is true, then parse the nal
   6194        and get the profile. Based on this, reject the clip playback */
   6195     if (first_frame == 0 && codec_type_parse == CODEC_TYPE_H264 &&
   6196             m_reject_avc_1080p_mp) {
   6197         first_frame = 1;
   6198         DEBUG_PRINT_ERROR("Parse nal to get the profile");
   6199         h264_parser->parse_nal((OMX_U8*)buffer->pBuffer, buffer->nFilledLen,
   6200                 NALU_TYPE_SPS);
   6201         m_profile = h264_parser->get_profile();
   6202         ret = is_video_session_supported();
   6203         if (ret) {
   6204             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,OMX_COMPONENT_GENERATE_EBD);
   6205             post_event(OMX_EventError, OMX_ErrorInvalidState,OMX_COMPONENT_GENERATE_EVENT);
   6206             /* Move the state to Invalid to avoid queueing of pending ETB to the driver */
   6207             m_state = OMX_StateInvalid;
   6208             return OMX_ErrorNone;
   6209         }
   6210     }
   6211 
   6212     DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   6213     /*for use buffer we need to memcpy the data*/
   6214     temp_buffer->buffer_len = buffer->nFilledLen;
   6215 
   6216     if (input_use_buffer) {
   6217         if (buffer->nFilledLen <= temp_buffer->buffer_len) {
   6218             if (arbitrary_bytes) {
   6219                 memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
   6220             } else {
   6221                 memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
   6222                         buffer->nFilledLen);
   6223             }
   6224         } else {
   6225             return OMX_ErrorBadParameter;
   6226         }
   6227 
   6228     }
   6229 
   6230     frameinfo.bufferaddr = temp_buffer->bufferaddr;
   6231     frameinfo.client_data = (void *) buffer;
   6232     frameinfo.datalen = temp_buffer->buffer_len;
   6233     frameinfo.flags = 0;
   6234     frameinfo.offset = buffer->nOffset;
   6235     frameinfo.pmem_fd = temp_buffer->pmem_fd;
   6236     frameinfo.pmem_offset = temp_buffer->offset;
   6237     frameinfo.timestamp = buffer->nTimeStamp;
   6238     if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
   6239         DEBUG_PRINT_LOW("ETB: dmx enabled");
   6240         if (m_demux_entries == 0) {
   6241             extract_demux_addr_offsets(buffer);
   6242         }
   6243 
   6244         DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%u",(unsigned int)m_demux_entries);
   6245         handle_demux_data(buffer);
   6246         frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
   6247         frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
   6248     } else {
   6249         frameinfo.desc_addr = NULL;
   6250         frameinfo.desc_size = 0;
   6251     }
   6252     if (!arbitrary_bytes) {
   6253         frameinfo.flags |= buffer->nFlags;
   6254     }
   6255 
   6256 #ifdef _ANDROID_
   6257     if (m_debug_timestamp) {
   6258         if (arbitrary_bytes) {
   6259             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   6260             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   6261         } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   6262             DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
   6263             m_timestamp_list.insert_ts(buffer->nTimeStamp);
   6264         }
   6265     }
   6266 #endif
   6267 
   6268 log_input_buffers((const char *)temp_buffer->bufferaddr, temp_buffer->buffer_len);
   6269 
   6270     if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   6271         frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   6272         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   6273     }
   6274 
   6275     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   6276         DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
   6277         frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
   6278         h264_scratch.nFilledLen = 0;
   6279         nal_count = 0;
   6280         look_ahead_nal = false;
   6281         frame_count = 0;
   6282         if (m_frame_parser.mutils)
   6283             m_frame_parser.mutils->initialize_frame_checking_environment();
   6284         m_frame_parser.flush();
   6285         h264_last_au_ts = LLONG_MAX;
   6286         h264_last_au_flags = 0;
   6287         memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   6288         m_demux_entries = 0;
   6289     }
   6290     struct v4l2_buffer buf;
   6291     struct v4l2_plane plane;
   6292     memset( (void *)&buf, 0, sizeof(buf));
   6293     memset( (void *)&plane, 0, sizeof(plane));
   6294     int rc;
   6295     unsigned long  print_count;
   6296     if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   6297         buf.flags = V4L2_QCOM_BUF_FLAG_EOS;
   6298         DEBUG_PRINT_HIGH("INPUT EOS reached") ;
   6299     }
   6300     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6301     buf.index = nPortIndex;
   6302     buf.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6303     buf.memory = V4L2_MEMORY_USERPTR;
   6304     plane.bytesused = temp_buffer->buffer_len;
   6305     plane.length = drv_ctx.ip_buf.buffer_size;
   6306     plane.m.userptr = (unsigned long)temp_buffer->bufferaddr -
   6307         (unsigned long)temp_buffer->offset;
   6308     plane.reserved[0] = temp_buffer->pmem_fd;
   6309     plane.reserved[1] = temp_buffer->offset;
   6310     plane.data_offset = 0;
   6311     buf.m.planes = &plane;
   6312     buf.length = 1;
   6313     if (frameinfo.timestamp >= LLONG_MAX) {
   6314         buf.flags |= V4L2_QCOM_BUF_TIMESTAMP_INVALID;
   6315     }
   6316     //assumption is that timestamp is in milliseconds
   6317     buf.timestamp.tv_sec = frameinfo.timestamp / 1000000;
   6318     buf.timestamp.tv_usec = (frameinfo.timestamp % 1000000);
   6319     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) ? V4L2_QCOM_BUF_FLAG_CODECCONFIG: 0;
   6320     buf.flags |= (buffer->nFlags & OMX_BUFFERFLAG_DECODEONLY) ? V4L2_QCOM_BUF_FLAG_DECODEONLY: 0;
   6321 
   6322     if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   6323         DEBUG_PRINT_LOW("Increment codec_config buffer counter");
   6324         android_atomic_inc(&m_queued_codec_config_count);
   6325     }
   6326 
   6327     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   6328     if (rc) {
   6329         DEBUG_PRINT_ERROR("Failed to qbuf Input buffer to driver");
   6330         return OMX_ErrorHardware;
   6331     }
   6332 
   6333     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   6334         codec_config_flag = false;
   6335     }
   6336     if (!streaming[OUTPUT_PORT]) {
   6337         enum v4l2_buf_type buf_type;
   6338         int ret,r;
   6339 
   6340         buf_type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   6341         DEBUG_PRINT_LOW("send_command_proxy(): Idle-->Executing");
   6342         ret=ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMON,&buf_type);
   6343         if (!ret) {
   6344             DEBUG_PRINT_HIGH("Streamon on OUTPUT Plane was successful");
   6345             streaming[OUTPUT_PORT] = true;
   6346         } else if (errno == EBUSY) {
   6347             DEBUG_PRINT_ERROR("Failed to call stream on OUTPUT due to HW_OVERLOAD");
   6348             post_event ((unsigned long)buffer, VDEC_S_SUCCESS,
   6349                     OMX_COMPONENT_GENERATE_EBD);
   6350             return OMX_ErrorInsufficientResources;
   6351         } else {
   6352             DEBUG_PRINT_ERROR("Failed to call streamon on OUTPUT");
   6353             DEBUG_PRINT_LOW("If Stream on failed no buffer should be queued");
   6354             post_event ((unsigned long)buffer,VDEC_S_SUCCESS,
   6355                     OMX_COMPONENT_GENERATE_EBD);
   6356             return OMX_ErrorBadParameter;
   6357         }
   6358     }
   6359     DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%u)",
   6360             frameinfo.bufferaddr, (long long)frameinfo.timestamp,
   6361             (unsigned int)frameinfo.datalen);
   6362 
   6363     return ret;
   6364 }
   6365 
   6366 /* ======================================================================
   6367    FUNCTION
   6368    omx_vdec::FillThisBuffer
   6369 
   6370    DESCRIPTION
   6371    IL client uses this method to release the frame buffer
   6372    after displaying them.
   6373 
   6374    PARAMETERS
   6375    None.
   6376 
   6377    RETURN VALUE
   6378    true/false
   6379 
   6380    ========================================================================== */
   6381 OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
   6382         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
   6383 {
   6384     unsigned nPortIndex = 0;
   6385     if (dynamic_buf_mode) {
   6386         private_handle_t *handle = NULL;
   6387         struct VideoDecoderOutputMetaData *meta;
   6388         unsigned int nPortIndex = 0;
   6389 
   6390         if (!buffer || !buffer->pBuffer) {
   6391             DEBUG_PRINT_ERROR("%s: invalid params: %p", __FUNCTION__, buffer);
   6392             return OMX_ErrorBadParameter;
   6393         }
   6394 
   6395         //get the buffer type and fd info
   6396         meta = (struct VideoDecoderOutputMetaData *)buffer->pBuffer;
   6397         handle = (private_handle_t *)meta->pHandle;
   6398         DEBUG_PRINT_LOW("FTB: metabuf: %p buftype: %d bufhndl: %p ", meta, meta->eType, meta->pHandle);
   6399 
   6400         if (!handle) {
   6401             DEBUG_PRINT_ERROR("FTB: Error: IL client passed an invalid buf handle - %p", handle);
   6402             return OMX_ErrorBadParameter;
   6403         }
   6404 
   6405         //Fill outputbuffer with buffer details, this will be sent to f/w during VIDIOC_QBUF
   6406         nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   6407         drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd = handle->fd;
   6408         drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr = (OMX_U8*) buffer;
   6409 
   6410         //Store private handle from GraphicBuffer
   6411         native_buffer[nPortIndex].privatehandle = handle;
   6412         native_buffer[nPortIndex].nativehandle = handle;
   6413 
   6414         //buffer->nAllocLen will be sizeof(struct VideoDecoderOutputMetaData). Overwrite
   6415         //this with a more sane size so that we don't compensate in rest of code
   6416         //We'll restore this size later on, so that it's transparent to client
   6417         buffer->nFilledLen = 0;
   6418         buffer->nAllocLen = handle->size;
   6419     }
   6420 
   6421 
   6422     if (m_state == OMX_StateInvalid) {
   6423         DEBUG_PRINT_ERROR("FTB in Invalid State");
   6424         return OMX_ErrorInvalidState;
   6425     }
   6426 
   6427     if (!m_out_bEnabled) {
   6428         DEBUG_PRINT_ERROR("ERROR:FTB incorrect state operation, output port is disabled.");
   6429         return OMX_ErrorIncorrectStateOperation;
   6430     }
   6431 
   6432     nPortIndex = buffer - client_buffers.get_il_buf_hdr();
   6433     if (buffer == NULL ||
   6434             (nPortIndex >= drv_ctx.op_buf.actualcount)) {
   6435         DEBUG_PRINT_ERROR("FTB: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   6436             nPortIndex, drv_ctx.op_buf.actualcount);
   6437         return OMX_ErrorBadParameter;
   6438     }
   6439 
   6440     if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
   6441         DEBUG_PRINT_ERROR("ERROR:FTB invalid port in header %u", (unsigned int)buffer->nOutputPortIndex);
   6442         return OMX_ErrorBadPortIndex;
   6443     }
   6444 
   6445     DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   6446     post_event((unsigned long) hComp, (unsigned long)buffer, m_fill_output_msg);
   6447     return OMX_ErrorNone;
   6448 }
   6449 /* ======================================================================
   6450    FUNCTION
   6451    omx_vdec::fill_this_buffer_proxy
   6452 
   6453    DESCRIPTION
   6454    IL client uses this method to release the frame buffer
   6455    after displaying them.
   6456 
   6457    PARAMETERS
   6458    None.
   6459 
   6460    RETURN VALUE
   6461    true/false
   6462 
   6463    ========================================================================== */
   6464 OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
   6465         OMX_IN OMX_HANDLETYPE        hComp,
   6466         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
   6467 {
   6468     OMX_ERRORTYPE nRet = OMX_ErrorNone;
   6469     OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
   6470     unsigned nPortIndex = 0;
   6471     struct vdec_fillbuffer_cmd fillbuffer;
   6472     struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
   6473     struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
   6474 
   6475     nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   6476 
   6477     if (bufferAdd == NULL || nPortIndex > drv_ctx.op_buf.actualcount) {
   6478         DEBUG_PRINT_ERROR("FTBProxy: ERROR: invalid buffer index, nPortIndex %u bufCount %u",
   6479             nPortIndex, drv_ctx.op_buf.actualcount);
   6480         return OMX_ErrorBadParameter;
   6481     }
   6482 
   6483     DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
   6484             bufferAdd, bufferAdd->pBuffer);
   6485     /*Return back the output buffer to client*/
   6486     if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
   6487         DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
   6488         buffer->nFilledLen = 0;
   6489         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   6490         return OMX_ErrorNone;
   6491     }
   6492 
   6493     if (dynamic_buf_mode) {
   6494         //map the buffer handle based on the size set on output port definition.
   6495         if (!secure_mode) {
   6496             drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr =
   6497                 (OMX_U8*)mmap(0, drv_ctx.op_buf.buffer_size,
   6498                        PROT_READ|PROT_WRITE, MAP_SHARED,
   6499                        drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd, 0);
   6500         }
   6501         drv_ctx.ptr_outputbuffer[nPortIndex].offset = 0;
   6502         drv_ctx.ptr_outputbuffer[nPortIndex].buffer_len = drv_ctx.op_buf.buffer_size;
   6503         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size = drv_ctx.op_buf.buffer_size;
   6504         buf_ref_add(drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd,
   6505                     drv_ctx.ptr_outputbuffer[nPortIndex].offset);
   6506     }
   6507 
   6508     pending_output_buffers++;
   6509     buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
   6510     if (!buffer) {
   6511        DEBUG_PRINT_ERROR("err: client_buffer ptr invalid");
   6512        return OMX_ErrorBadParameter;
   6513     }
   6514     ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
   6515     if (ptr_respbuffer) {
   6516         ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
   6517     }
   6518 
   6519     if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
   6520         DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
   6521         buffer->nFilledLen = 0;
   6522         m_cb.FillBufferDone (hComp,m_app_data,buffer);
   6523         pending_output_buffers--;
   6524         return OMX_ErrorBadParameter;
   6525     }
   6526 
   6527     int rc = 0;
   6528     struct v4l2_buffer buf;
   6529     struct v4l2_plane plane[VIDEO_MAX_PLANES];
   6530     memset( (void *)&buf, 0, sizeof(buf));
   6531     memset( (void *)plane, 0, (sizeof(struct v4l2_plane)*VIDEO_MAX_PLANES));
   6532     unsigned int extra_idx = 0;
   6533 
   6534     buf.index = nPortIndex;
   6535     buf.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   6536     buf.memory = V4L2_MEMORY_USERPTR;
   6537     plane[0].bytesused = buffer->nFilledLen;
   6538     plane[0].length = drv_ctx.op_buf.buffer_size;
   6539     plane[0].m.userptr =
   6540         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr -
   6541         (unsigned long)drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   6542     plane[0].reserved[0] = drv_ctx.ptr_outputbuffer[nPortIndex].pmem_fd;
   6543     plane[0].reserved[1] = drv_ctx.ptr_outputbuffer[nPortIndex].offset;
   6544     plane[0].data_offset = 0;
   6545     extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   6546     if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   6547         plane[extra_idx].bytesused = 0;
   6548         plane[extra_idx].length = drv_ctx.extradata_info.buffer_size;
   6549         plane[extra_idx].m.userptr = (long unsigned int) (drv_ctx.extradata_info.uaddr + nPortIndex * drv_ctx.extradata_info.buffer_size);
   6550 #ifdef USE_ION
   6551         plane[extra_idx].reserved[0] = drv_ctx.extradata_info.ion.fd_ion_data.fd;
   6552 #endif
   6553         plane[extra_idx].reserved[1] = nPortIndex * drv_ctx.extradata_info.buffer_size;
   6554         plane[extra_idx].data_offset = 0;
   6555     } else if (extra_idx >= VIDEO_MAX_PLANES) {
   6556         DEBUG_PRINT_ERROR("Extradata index higher than expected: %u", extra_idx);
   6557         return OMX_ErrorBadParameter;
   6558     }
   6559     buf.m.planes = plane;
   6560     buf.length = drv_ctx.num_planes;
   6561     DEBUG_PRINT_LOW("SENDING FTB TO F/W - fd[0] = %d fd[1] = %d offset[1] = %d",
   6562              plane[0].reserved[0],plane[extra_idx].reserved[0], plane[extra_idx].reserved[1]);
   6563 
   6564     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_QBUF, &buf);
   6565     if (rc) {
   6566         /*TODO: How to handle this case */
   6567         DEBUG_PRINT_ERROR("Failed to qbuf to driver");
   6568     }
   6569     return OMX_ErrorNone;
   6570 }
   6571 
   6572 /* ======================================================================
   6573    FUNCTION
   6574    omx_vdec::SetCallbacks
   6575 
   6576    DESCRIPTION
   6577    Set the callbacks.
   6578 
   6579    PARAMETERS
   6580    None.
   6581 
   6582    RETURN VALUE
   6583    OMX Error None if everything successful.
   6584 
   6585    ========================================================================== */
   6586 OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
   6587         OMX_IN OMX_CALLBACKTYPE* callbacks,
   6588         OMX_IN OMX_PTR             appData)
   6589 {
   6590     (void) hComp;
   6591     m_cb       = *callbacks;
   6592     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
   6593             m_cb.EventHandler,m_cb.FillBufferDone);
   6594     m_app_data =    appData;
   6595     return OMX_ErrorNotImplemented;
   6596 }
   6597 
   6598 /* ======================================================================
   6599    FUNCTION
   6600    omx_vdec::ComponentDeInit
   6601 
   6602    DESCRIPTION
   6603    Destroys the component and release memory allocated to the heap.
   6604 
   6605    PARAMETERS
   6606    <TBD>.
   6607 
   6608    RETURN VALUE
   6609    OMX Error None if everything successful.
   6610 
   6611    ========================================================================== */
   6612 OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
   6613 {
   6614    (void) hComp;
   6615 #ifdef _ANDROID_
   6616     if (iDivXDrmDecrypt) {
   6617         delete iDivXDrmDecrypt;
   6618         iDivXDrmDecrypt=NULL;
   6619     }
   6620 #endif //_ANDROID_
   6621 
   6622     unsigned i = 0;
   6623     if (OMX_StateLoaded != m_state) {
   6624         DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d",\
   6625                 m_state);
   6626         DEBUG_PRINT_ERROR("Playback Ended - FAILED");
   6627     } else {
   6628         DEBUG_PRINT_HIGH("Playback Ended - PASSED");
   6629     }
   6630 
   6631     /*Check if the output buffers have to be cleaned up*/
   6632     if (m_out_mem_ptr) {
   6633         DEBUG_PRINT_LOW("Freeing the Output Memory");
   6634         for (i = 0; i < drv_ctx.op_buf.actualcount; i++ ) {
   6635             free_output_buffer (&m_out_mem_ptr[i]);
   6636         }
   6637 #ifdef _ANDROID_ICS_
   6638         memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
   6639 #endif
   6640     }
   6641 
   6642     /*Check if the input buffers have to be cleaned up*/
   6643     if (m_inp_mem_ptr || m_inp_heap_ptr) {
   6644         DEBUG_PRINT_LOW("Freeing the Input Memory");
   6645         for (i = 0; i<drv_ctx.ip_buf.actualcount; i++ ) {
   6646             if (m_inp_mem_ptr)
   6647                 free_input_buffer (i,&m_inp_mem_ptr[i]);
   6648             else
   6649                 free_input_buffer (i,NULL);
   6650         }
   6651     }
   6652     free_input_buffer_header();
   6653     free_output_buffer_header();
   6654     if (h264_scratch.pBuffer) {
   6655         free(h264_scratch.pBuffer);
   6656         h264_scratch.pBuffer = NULL;
   6657     }
   6658 
   6659     if (h264_parser) {
   6660         delete h264_parser;
   6661         h264_parser = NULL;
   6662     }
   6663 
   6664     if (m_frame_parser.mutils) {
   6665         DEBUG_PRINT_LOW("Free utils parser");
   6666         delete (m_frame_parser.mutils);
   6667         m_frame_parser.mutils = NULL;
   6668     }
   6669 
   6670     if (m_platform_list) {
   6671         free(m_platform_list);
   6672         m_platform_list = NULL;
   6673     }
   6674     if (m_vendor_config.pData) {
   6675         free(m_vendor_config.pData);
   6676         m_vendor_config.pData = NULL;
   6677     }
   6678 
   6679     // Reset counters in mesg queues
   6680     m_ftb_q.m_size=0;
   6681     m_cmd_q.m_size=0;
   6682     m_etb_q.m_size=0;
   6683     m_ftb_q.m_read = m_ftb_q.m_write =0;
   6684     m_cmd_q.m_read = m_cmd_q.m_write =0;
   6685     m_etb_q.m_read = m_etb_q.m_write =0;
   6686 #ifdef _ANDROID_
   6687     if (m_debug_timestamp) {
   6688         m_timestamp_list.reset_ts_list();
   6689     }
   6690 #endif
   6691 
   6692     DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
   6693     //(void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
   6694     // NULL);
   6695     DEBUG_PRINT_HIGH("Close the driver instance");
   6696 
   6697     if (m_debug.infile) {
   6698         fclose(m_debug.infile);
   6699         m_debug.infile = NULL;
   6700     }
   6701     if (m_debug.outfile) {
   6702         fclose(m_debug.outfile);
   6703         m_debug.outfile = NULL;
   6704     }
   6705 #ifdef OUTPUT_EXTRADATA_LOG
   6706     if (outputExtradataFile)
   6707         fclose (outputExtradataFile);
   6708 #endif
   6709     DEBUG_PRINT_INFO("omx_vdec::component_deinit() complete");
   6710     return OMX_ErrorNone;
   6711 }
   6712 
   6713 /* ======================================================================
   6714    FUNCTION
   6715    omx_vdec::UseEGLImage
   6716 
   6717    DESCRIPTION
   6718    OMX Use EGL Image method implementation <TBD>.
   6719 
   6720    PARAMETERS
   6721    <TBD>.
   6722 
   6723    RETURN VALUE
   6724    Not Implemented error.
   6725 
   6726    ========================================================================== */
   6727 OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE     hComp,
   6728         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
   6729         OMX_IN OMX_U32                        port,
   6730         OMX_IN OMX_PTR                     appData,
   6731         OMX_IN void*                      eglImage)
   6732 {
   6733     (void) appData;
   6734     OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
   6735     OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
   6736     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
   6737 
   6738 #ifdef USE_EGL_IMAGE_GPU
   6739     PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
   6740     EGLint fd = -1, offset = 0,pmemPtr = 0;
   6741 #else
   6742     int fd = -1, offset = 0;
   6743 #endif
   6744     DEBUG_PRINT_HIGH("use EGL image support for decoder");
   6745     if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
   6746         DEBUG_PRINT_ERROR("Invalid EGL image");
   6747     }
   6748 #ifdef USE_EGL_IMAGE_GPU
   6749     if (m_display_id == NULL) {
   6750         DEBUG_PRINT_ERROR("Display ID is not set by IL client");
   6751         return OMX_ErrorInsufficientResources;
   6752     }
   6753     egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
   6754         eglGetProcAddress("eglQueryImageKHR");
   6755     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE, &fd);
   6756     egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET, &offset);
   6757     egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
   6758 #else //with OMX test app
   6759     struct temp_egl {
   6760         int pmem_fd;
   6761         int offset;
   6762     };
   6763     struct temp_egl *temp_egl_id = NULL;
   6764     void * pmemPtr = (void *) eglImage;
   6765     temp_egl_id = (struct temp_egl *)eglImage;
   6766     if (temp_egl_id != NULL) {
   6767         fd = temp_egl_id->pmem_fd;
   6768         offset = temp_egl_id->offset;
   6769     }
   6770 #endif
   6771     if (fd < 0) {
   6772         DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d",fd);
   6773         return OMX_ErrorInsufficientResources;
   6774     }
   6775     pmem_info.pmem_fd = (OMX_U32) fd;
   6776     pmem_info.offset = (OMX_U32) offset;
   6777     pmem_entry.entry = (void *) &pmem_info;
   6778     pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   6779     pmem_list.entryList = &pmem_entry;
   6780     pmem_list.nEntries = 1;
   6781     ouput_egl_buffers = true;
   6782     if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
   6783                 (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
   6784                 (OMX_U8 *)pmemPtr)) {
   6785         DEBUG_PRINT_ERROR("use buffer call failed for egl image");
   6786         return OMX_ErrorInsufficientResources;
   6787     }
   6788     return OMX_ErrorNone;
   6789 }
   6790 
   6791 /* ======================================================================
   6792    FUNCTION
   6793    omx_vdec::ComponentRoleEnum
   6794 
   6795    DESCRIPTION
   6796    OMX Component Role Enum method implementation.
   6797 
   6798    PARAMETERS
   6799    <TBD>.
   6800 
   6801    RETURN VALUE
   6802    OMX Error None if everything is successful.
   6803    ========================================================================== */
   6804 OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
   6805         OMX_OUT OMX_U8*        role,
   6806         OMX_IN OMX_U32        index)
   6807 {
   6808     (void) hComp;
   6809     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   6810 
   6811     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
   6812         if ((0 == index) && role) {
   6813             strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
   6814             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6815         } else {
   6816             eRet = OMX_ErrorNoMore;
   6817         }
   6818     }
   6819     if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
   6820         if ((0 == index) && role) {
   6821             strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
   6822             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6823         } else {
   6824             eRet = OMX_ErrorNoMore;
   6825         }
   6826     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
   6827         if ((0 == index) && role) {
   6828             strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
   6829             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6830         } else {
   6831             DEBUG_PRINT_LOW("No more roles");
   6832             eRet = OMX_ErrorNoMore;
   6833         }
   6834     }
   6835 
   6836     else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
   6837             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))) {
   6838         if ((0 == index) && role) {
   6839             strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
   6840             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6841         } else {
   6842             DEBUG_PRINT_LOW("No more roles");
   6843             eRet = OMX_ErrorNoMore;
   6844         }
   6845     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
   6846         if ((0 == index) && role) {
   6847             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
   6848             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6849         } else {
   6850             DEBUG_PRINT_LOW("No more roles");
   6851             eRet = OMX_ErrorNoMore;
   6852         }
   6853     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mvc", OMX_MAX_STRINGNAME_SIZE)) {
   6854         if ((0 == index) && role) {
   6855             strlcpy((char *)role, "video_decoder.mvc", OMX_MAX_STRINGNAME_SIZE);
   6856             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6857         } else {
   6858             DEBUG_PRINT_LOW("No more roles");
   6859             eRet = OMX_ErrorNoMore;
   6860         }
   6861     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.hevc", OMX_MAX_STRINGNAME_SIZE)) {
   6862         if ((0 == index) && role) {
   6863             strlcpy((char *)role, "video_decoder.hevc", OMX_MAX_STRINGNAME_SIZE);
   6864             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
   6865         } else {
   6866             DEBUG_PRINT_LOW("No more roles");
   6867             eRet = OMX_ErrorNoMore;
   6868         }
   6869     } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
   6870             (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
   6871           ) {
   6872         if ((0 == index) && role) {
   6873             strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
   6874             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6875         } else {
   6876             DEBUG_PRINT_LOW("No more roles");
   6877             eRet = OMX_ErrorNoMore;
   6878         }
   6879     } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
   6880         if ((0 == index) && role) {
   6881             strlcpy((char *)role, "video_decoder.vp8",OMX_MAX_STRINGNAME_SIZE);
   6882             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
   6883         } else {
   6884             DEBUG_PRINT_LOW("No more roles");
   6885             eRet = OMX_ErrorNoMore;
   6886         }
   6887     } else {
   6888         DEBUG_PRINT_ERROR("ERROR:Querying Role on Unknown Component");
   6889         eRet = OMX_ErrorInvalidComponentName;
   6890     }
   6891     return eRet;
   6892 }
   6893 
   6894 
   6895 
   6896 
   6897 /* ======================================================================
   6898    FUNCTION
   6899    omx_vdec::AllocateDone
   6900 
   6901    DESCRIPTION
   6902    Checks if entire buffer pool is allocated by IL Client or not.
   6903    Need this to move to IDLE state.
   6904 
   6905    PARAMETERS
   6906    None.
   6907 
   6908    RETURN VALUE
   6909    true/false.
   6910 
   6911    ========================================================================== */
   6912 bool omx_vdec::allocate_done(void)
   6913 {
   6914     bool bRet = false;
   6915     bool bRet_In = false;
   6916     bool bRet_Out = false;
   6917 
   6918     bRet_In = allocate_input_done();
   6919     bRet_Out = allocate_output_done();
   6920 
   6921     if (bRet_In && bRet_Out) {
   6922         bRet = true;
   6923     }
   6924 
   6925     return bRet;
   6926 }
   6927 /* ======================================================================
   6928    FUNCTION
   6929    omx_vdec::AllocateInputDone
   6930 
   6931    DESCRIPTION
   6932    Checks if I/P buffer pool is allocated by IL Client or not.
   6933 
   6934    PARAMETERS
   6935    None.
   6936 
   6937    RETURN VALUE
   6938    true/false.
   6939 
   6940    ========================================================================== */
   6941 bool omx_vdec::allocate_input_done(void)
   6942 {
   6943     bool bRet = false;
   6944     unsigned i=0;
   6945 
   6946     if (m_inp_mem_ptr == NULL) {
   6947         return bRet;
   6948     }
   6949     if (m_inp_mem_ptr ) {
   6950         for (; i<drv_ctx.ip_buf.actualcount; i++) {
   6951             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
   6952                 break;
   6953             }
   6954         }
   6955     }
   6956     if (i == drv_ctx.ip_buf.actualcount) {
   6957         bRet = true;
   6958         DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
   6959     }
   6960     if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
   6961         m_inp_bPopulated = OMX_TRUE;
   6962     }
   6963     return bRet;
   6964 }
   6965 /* ======================================================================
   6966    FUNCTION
   6967    omx_vdec::AllocateOutputDone
   6968 
   6969    DESCRIPTION
   6970    Checks if entire O/P buffer pool is allocated by IL Client or not.
   6971 
   6972    PARAMETERS
   6973    None.
   6974 
   6975    RETURN VALUE
   6976    true/false.
   6977 
   6978    ========================================================================== */
   6979 bool omx_vdec::allocate_output_done(void)
   6980 {
   6981     bool bRet = false;
   6982     unsigned j=0;
   6983 
   6984     if (m_out_mem_ptr == NULL) {
   6985         return bRet;
   6986     }
   6987 
   6988     if (m_out_mem_ptr) {
   6989         for (; j < drv_ctx.op_buf.actualcount; j++) {
   6990             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
   6991                 break;
   6992             }
   6993         }
   6994     }
   6995 
   6996     if (j == drv_ctx.op_buf.actualcount) {
   6997         bRet = true;
   6998         DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
   6999         if (m_out_bEnabled)
   7000             m_out_bPopulated = OMX_TRUE;
   7001     }
   7002 
   7003     return bRet;
   7004 }
   7005 
   7006 /* ======================================================================
   7007    FUNCTION
   7008    omx_vdec::ReleaseDone
   7009 
   7010    DESCRIPTION
   7011    Checks if IL client has released all the buffers.
   7012 
   7013    PARAMETERS
   7014    None.
   7015 
   7016    RETURN VALUE
   7017    true/false
   7018 
   7019    ========================================================================== */
   7020 bool omx_vdec::release_done(void)
   7021 {
   7022     bool bRet = false;
   7023 
   7024     if (release_input_done()) {
   7025         if (release_output_done()) {
   7026             bRet = true;
   7027         }
   7028     }
   7029     return bRet;
   7030 }
   7031 
   7032 
   7033 /* ======================================================================
   7034    FUNCTION
   7035    omx_vdec::ReleaseOutputDone
   7036 
   7037    DESCRIPTION
   7038    Checks if IL client has released all the buffers.
   7039 
   7040    PARAMETERS
   7041    None.
   7042 
   7043    RETURN VALUE
   7044    true/false
   7045 
   7046    ========================================================================== */
   7047 bool omx_vdec::release_output_done(void)
   7048 {
   7049     bool bRet = false;
   7050     unsigned i=0,j=0;
   7051 
   7052     DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
   7053     if (m_out_mem_ptr) {
   7054         for (; j < drv_ctx.op_buf.actualcount ; j++) {
   7055             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
   7056                 break;
   7057             }
   7058         }
   7059         if (j == drv_ctx.op_buf.actualcount) {
   7060             m_out_bm_count = 0;
   7061             bRet = true;
   7062         }
   7063     } else {
   7064         m_out_bm_count = 0;
   7065         bRet = true;
   7066     }
   7067     return bRet;
   7068 }
   7069 /* ======================================================================
   7070    FUNCTION
   7071    omx_vdec::ReleaseInputDone
   7072 
   7073    DESCRIPTION
   7074    Checks if IL client has released all the buffers.
   7075 
   7076    PARAMETERS
   7077    None.
   7078 
   7079    RETURN VALUE
   7080    true/false
   7081 
   7082    ========================================================================== */
   7083 bool omx_vdec::release_input_done(void)
   7084 {
   7085     bool bRet = false;
   7086     unsigned i=0,j=0;
   7087 
   7088     DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
   7089     if (m_inp_mem_ptr) {
   7090         for (; j<drv_ctx.ip_buf.actualcount; j++) {
   7091             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
   7092                 break;
   7093             }
   7094         }
   7095         if (j==drv_ctx.ip_buf.actualcount) {
   7096             bRet = true;
   7097         }
   7098     } else {
   7099         bRet = true;
   7100     }
   7101     return bRet;
   7102 }
   7103 
   7104 OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
   7105         OMX_BUFFERHEADERTYPE * buffer)
   7106 {
   7107     OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
   7108     if (!buffer || (buffer - m_out_mem_ptr) >= (int)drv_ctx.op_buf.actualcount) {
   7109         DEBUG_PRINT_ERROR("[FBD] ERROR in ptr(%p)", buffer);
   7110         return OMX_ErrorBadParameter;
   7111     } else if (output_flush_progress) {
   7112         DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
   7113         buffer->nFilledLen = 0;
   7114         buffer->nTimeStamp = 0;
   7115         buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
   7116         buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7117         buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
   7118     }
   7119 
   7120     if (m_debug_extradata) {
   7121         if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
   7122             DEBUG_PRINT_HIGH("***************************************************");
   7123             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   7124             DEBUG_PRINT_HIGH("***************************************************");
   7125         }
   7126 
   7127         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   7128             DEBUG_PRINT_HIGH("***************************************************");
   7129             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   7130             DEBUG_PRINT_HIGH("***************************************************");
   7131         }
   7132     }
   7133 
   7134 
   7135     DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
   7136             buffer, buffer->pBuffer);
   7137     pending_output_buffers --;
   7138 
   7139     if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   7140         DEBUG_PRINT_HIGH("Output EOS has been reached");
   7141         if (!output_flush_progress)
   7142             post_event((unsigned)NULL, (unsigned)NULL,
   7143                     OMX_COMPONENT_GENERATE_EOS_DONE);
   7144 
   7145         if (psource_frame) {
   7146             m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
   7147             psource_frame = NULL;
   7148         }
   7149         if (pdest_frame) {
   7150             pdest_frame->nFilledLen = 0;
   7151             m_input_free_q.insert_entry((unsigned long) pdest_frame,(unsigned)NULL,
   7152                     (unsigned)NULL);
   7153             pdest_frame = NULL;
   7154         }
   7155     }
   7156 
   7157     if (!output_flush_progress && (buffer->nFilledLen > 0)) {
   7158         DEBUG_PRINT_LOW("Processing extradata");
   7159         handle_extradata(buffer);
   7160     }
   7161 
   7162 #ifdef OUTPUT_EXTRADATA_LOG
   7163     if (outputExtradataFile) {
   7164         int buf_index = buffer - m_out_mem_ptr;
   7165         OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr);
   7166 
   7167         OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
   7168         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   7169             ((unsigned long)(pBuffer + buffer->nOffset + buffer->nFilledLen + 3)&(~3));
   7170 
   7171         while (p_extra && (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
   7172             DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%x",
   7173                                     p_extra->nSize, p_extra->eType);
   7174             fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
   7175 
   7176             if (p_extra->eType == OMX_ExtraDataNone) {
   7177                 break;
   7178             }
   7179             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   7180         }
   7181     }
   7182 #endif
   7183 
   7184     /* For use buffer we need to copy the data */
   7185     if (!output_flush_progress) {
   7186         /* This is the error check for non-recoverable errros */
   7187         bool is_duplicate_ts_valid = true;
   7188         bool is_interlaced = (drv_ctx.interlace != VDEC_InterlaceFrameProgressive);
   7189 
   7190         if (output_capability == V4L2_PIX_FMT_MPEG4 ||
   7191                 output_capability == V4L2_PIX_FMT_MPEG2 ||
   7192                 output_capability == V4L2_PIX_FMT_DIVX ||
   7193                 output_capability == V4L2_PIX_FMT_DIVX_311)
   7194             is_duplicate_ts_valid = false;
   7195 
   7196         if ((output_capability == V4L2_PIX_FMT_H264 ||
   7197                 output_capability == V4L2_PIX_FMT_H264_MVC) &&
   7198                 is_interlaced) {
   7199             if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF) {
   7200                 is_interlaced = false;
   7201             }
   7202         }
   7203 
   7204         if (buffer->nFilledLen > 0) {
   7205             time_stamp_dts.get_next_timestamp(buffer,
   7206                     is_interlaced && is_duplicate_ts_valid);
   7207             if (m_debug_timestamp) {
   7208                 {
   7209                     OMX_TICKS expected_ts = 0;
   7210                     m_timestamp_list.pop_min_ts(expected_ts);
   7211                     if (is_interlaced && is_duplicate_ts_valid) {
   7212                         m_timestamp_list.pop_min_ts(expected_ts);
   7213                     }
   7214                     DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
   7215                             buffer->nTimeStamp, expected_ts);
   7216 
   7217                     if (buffer->nTimeStamp != expected_ts) {
   7218                         DEBUG_PRINT_ERROR("ERROR in omx_vdec::async_message_process timestamp Check");
   7219                     }
   7220                 }
   7221             }
   7222         }
   7223         }
   7224 
   7225     /* Since we're passing around handles, adjust nFilledLen and nAllocLen
   7226      * to size of the handle.  Do it _after_ handle_extradata() which
   7227      * requires the respective sizes to be accurate. */
   7228     if (dynamic_buf_mode) {
   7229         buffer->nAllocLen = sizeof(struct VideoDecoderOutputMetaData);
   7230         buffer->nFilledLen = buffer->nFilledLen ?
   7231             sizeof(struct VideoDecoderOutputMetaData) : 0;
   7232     }
   7233     if (m_cb.FillBufferDone) {
   7234         if (buffer->nFilledLen > 0) {
   7235             if (arbitrary_bytes)
   7236                 adjust_timestamp(buffer->nTimeStamp);
   7237             else
   7238                 set_frame_rate(buffer->nTimeStamp);
   7239 
   7240             if (perf_flag) {
   7241                 if (!proc_frms) {
   7242                     dec_time.stop();
   7243                     latency = dec_time.processing_time_us() - latency;
   7244                     DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
   7245                     dec_time.start();
   7246                     fps_metrics.start();
   7247                 }
   7248                 proc_frms++;
   7249                 if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   7250                     OMX_U64 proc_time = 0;
   7251                     fps_metrics.stop();
   7252                     proc_time = fps_metrics.processing_time_us();
   7253                     DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%u) proc_time(%.2f)S fps(%.2f)",
   7254                             (unsigned int)proc_frms, (float)proc_time / 1e6,
   7255                             (float)(1e6 * proc_frms) / proc_time);
   7256                     proc_frms = 0;
   7257                 }
   7258             }
   7259         }
   7260         if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
   7261             prev_ts = LLONG_MAX;
   7262             rst_prev_ts = true;
   7263         }
   7264 
   7265         pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   7266             ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
   7267              buffer->pPlatformPrivate)->entryList->entry;
   7268         DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %lu",pPMEMInfo->pmem_fd);
   7269         OMX_BUFFERHEADERTYPE *il_buffer;
   7270         il_buffer = client_buffers.get_il_buf_hdr(buffer);
   7271 
   7272         if (il_buffer && m_last_rendered_TS >= 0) {
   7273             int current_framerate = (int)(drv_ctx.frame_rate.fps_numerator /drv_ctx.frame_rate.fps_denominator);
   7274             OMX_TICKS ts_delta = (OMX_TICKS)llabs(il_buffer->nTimeStamp - m_last_rendered_TS);
   7275 
   7276             // Current frame can be send for rendering if
   7277             // (a) current FPS is <=  60
   7278             // (b) is the next frame after the frame with TS 0
   7279             // (c) is the first frame after seek
   7280             // (d) the delta TS b\w two consecutive frames is > 16 ms
   7281             // (e) its TS is equal to previous frame TS
   7282             // (f) if marked EOS
   7283 
   7284             if(current_framerate <= 60 || m_last_rendered_TS == 0 ||
   7285                il_buffer->nTimeStamp == 0 || ts_delta >= 16000 ||
   7286                ts_delta == 0 || (il_buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
   7287                m_last_rendered_TS = il_buffer->nTimeStamp;
   7288             } else {
   7289                //mark for droping
   7290                buffer->nFilledLen = 0;
   7291             }
   7292 
   7293             DEBUG_PRINT_LOW(" -- %s Frame -- info:: fps(%d) lastRenderTime(%lld) bufferTs(%lld) ts_delta(%lld)",
   7294                               buffer->nFilledLen? "Rendering":"Dropping",current_framerate,m_last_rendered_TS,
   7295                               il_buffer->nTimeStamp,ts_delta);
   7296         }
   7297 
   7298         if (il_buffer) {
   7299             log_output_buffers(il_buffer);
   7300             if (dynamic_buf_mode) {
   7301                 unsigned int nPortIndex = 0;
   7302                 nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)client_buffers.get_il_buf_hdr());
   7303 
   7304                 if (!secure_mode) {
   7305                     munmap(drv_ctx.ptr_outputbuffer[nPortIndex].bufferaddr,
   7306                         drv_ctx.ptr_outputbuffer[nPortIndex].mmaped_size);
   7307                 }
   7308 
   7309                 //Clear graphic buffer handles in dynamic mode
   7310                 native_buffer[nPortIndex].privatehandle = NULL;
   7311                 native_buffer[nPortIndex].nativehandle = NULL;
   7312             }
   7313             m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
   7314         } else {
   7315             DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
   7316             return OMX_ErrorBadParameter;
   7317         }
   7318         DEBUG_PRINT_LOW("After Fill Buffer Done callback %lu",pPMEMInfo->pmem_fd);
   7319     } else {
   7320         return OMX_ErrorBadParameter;
   7321     }
   7322 
   7323 #ifdef ADAPTIVE_PLAYBACK_SUPPORTED
   7324     if (m_smoothstreaming_mode && m_out_mem_ptr) {
   7325         OMX_U32 buf_index = buffer - m_out_mem_ptr;
   7326         BufferDim_t dim;
   7327         private_handle_t *private_handle = NULL;
   7328         dim.sliceWidth = framesize.nWidth;
   7329         dim.sliceHeight = framesize.nHeight;
   7330         if (native_buffer[buf_index].privatehandle)
   7331             private_handle = native_buffer[buf_index].privatehandle;
   7332         if (private_handle) {
   7333             DEBUG_PRINT_LOW("set metadata: update buf-geometry with stride %d slice %d",
   7334                 dim.sliceWidth, dim.sliceHeight);
   7335             setMetaData(private_handle, UPDATE_BUFFER_GEOMETRY, (void*)&dim);
   7336         }
   7337   }
   7338 #endif
   7339 
   7340     return OMX_ErrorNone;
   7341 }
   7342 
   7343 OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
   7344         OMX_BUFFERHEADERTYPE* buffer)
   7345 {
   7346 
   7347     if (buffer == NULL || ((buffer - m_inp_mem_ptr) > (int)drv_ctx.ip_buf.actualcount)) {
   7348         DEBUG_PRINT_ERROR("empty_buffer_done: ERROR bufhdr = %p", buffer);
   7349         return OMX_ErrorBadParameter;
   7350     }
   7351 
   7352     DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p, bufhdr->nFlags = %x",
   7353             buffer, buffer->pBuffer, buffer->nFlags);
   7354     pending_input_buffers--;
   7355 
   7356     if (arbitrary_bytes) {
   7357         if (pdest_frame == NULL && input_flush_progress == false) {
   7358             DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
   7359             pdest_frame = buffer;
   7360             buffer->nFilledLen = 0;
   7361             buffer->nTimeStamp = LLONG_MAX;
   7362             push_input_buffer (hComp);
   7363         } else {
   7364             DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
   7365             buffer->nFilledLen = 0;
   7366             if (!m_input_free_q.insert_entry((unsigned long)buffer,
   7367                         (unsigned)NULL, (unsigned)NULL)) {
   7368                 DEBUG_PRINT_ERROR("ERROR:i/p free Queue is FULL Error");
   7369             }
   7370         }
   7371     } else if (m_cb.EmptyBufferDone) {
   7372         buffer->nFilledLen = 0;
   7373         if (input_use_buffer == true) {
   7374             buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
   7375         }
   7376         m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
   7377     }
   7378     return OMX_ErrorNone;
   7379 }
   7380 
   7381 int omx_vdec::async_message_process (void *context, void* message)
   7382 {
   7383     omx_vdec* omx = NULL;
   7384     struct vdec_msginfo *vdec_msg = NULL;
   7385     OMX_BUFFERHEADERTYPE* omxhdr = NULL;
   7386     struct v4l2_buffer *v4l2_buf_ptr = NULL;
   7387     struct vdec_output_frameinfo *output_respbuf = NULL;
   7388     int rc=1;
   7389     if (context == NULL || message == NULL) {
   7390         DEBUG_PRINT_ERROR("FATAL ERROR in omx_vdec::async_message_process NULL Check");
   7391         return -1;
   7392     }
   7393     vdec_msg = (struct vdec_msginfo *)message;
   7394 
   7395     omx = reinterpret_cast<omx_vdec*>(context);
   7396 
   7397     switch (vdec_msg->msgcode) {
   7398 
   7399         case VDEC_MSG_EVT_HW_ERROR:
   7400             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7401                     OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   7402             break;
   7403 
   7404         case VDEC_MSG_EVT_HW_OVERLOAD:
   7405             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7406                     OMX_COMPONENT_GENERATE_HARDWARE_OVERLOAD);
   7407             break;
   7408 
   7409         case VDEC_MSG_EVT_HW_UNSUPPORTED:
   7410             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7411                     OMX_COMPONENT_GENERATE_UNSUPPORTED_SETTING);
   7412             break;
   7413 
   7414         case VDEC_MSG_RESP_START_DONE:
   7415             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7416                     OMX_COMPONENT_GENERATE_START_DONE);
   7417             break;
   7418 
   7419         case VDEC_MSG_RESP_STOP_DONE:
   7420             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7421                     OMX_COMPONENT_GENERATE_STOP_DONE);
   7422             break;
   7423 
   7424         case VDEC_MSG_RESP_RESUME_DONE:
   7425             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7426                     OMX_COMPONENT_GENERATE_RESUME_DONE);
   7427             break;
   7428 
   7429         case VDEC_MSG_RESP_PAUSE_DONE:
   7430             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7431                     OMX_COMPONENT_GENERATE_PAUSE_DONE);
   7432             break;
   7433 
   7434         case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
   7435             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7436                     OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
   7437             break;
   7438         case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
   7439             omx->post_event ((unsigned)NULL, vdec_msg->status_code,\
   7440                     OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
   7441             break;
   7442         case VDEC_MSG_RESP_INPUT_FLUSHED:
   7443         case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
   7444 
   7445             /* omxhdr = (OMX_BUFFERHEADERTYPE* )
   7446                vdec_msg->msgdata.input_frame_clientdata; */
   7447 
   7448             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.input_frame_clientdata;
   7449             omxhdr=omx->m_inp_mem_ptr+v4l2_buf_ptr->index;
   7450             if (omxhdr == NULL ||
   7451                     ((omxhdr - omx->m_inp_mem_ptr) > (int)omx->drv_ctx.ip_buf.actualcount) ) {
   7452                 omxhdr = NULL;
   7453                 vdec_msg->status_code = VDEC_S_EFATAL;
   7454                 break;
   7455             }
   7456             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_INPUT_UNSUPPORTED) {
   7457                 DEBUG_PRINT_HIGH("Unsupported input");
   7458                 omx->omx_report_error ();
   7459             }
   7460             if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   7461                 omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   7462                 vdec_msg->status_code = VDEC_S_INPUT_BITSTREAM_ERR;
   7463             }
   7464             if (omxhdr->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   7465 
   7466                 DEBUG_PRINT_LOW("Decrement codec_config buffer counter");
   7467                 android_atomic_dec(&omx->m_queued_codec_config_count);
   7468                 if ((android_atomic_add(0, &omx->m_queued_codec_config_count) == 0) &&
   7469                     BITMASK_PRESENT(&omx->m_flags, OMX_COMPONENT_FLUSH_DEFERRED)) {
   7470                     DEBUG_PRINT_LOW("sem post for CODEC CONFIG buffer");
   7471                     sem_post(&omx->m_safe_flush);
   7472                 }
   7473             }
   7474 
   7475             omx->post_event ((unsigned long)omxhdr,vdec_msg->status_code,
   7476                     OMX_COMPONENT_GENERATE_EBD);
   7477             break;
   7478         case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
   7479             int64_t *timestamp;
   7480             timestamp = (int64_t *) malloc(sizeof(int64_t));
   7481             if (timestamp) {
   7482                 *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
   7483                 omx->post_event ((unsigned long)timestamp, vdec_msg->status_code,
   7484                         OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
   7485                 DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
   7486                         (long long)vdec_msg->msgdata.output_frame.time_stamp);
   7487             }
   7488             break;
   7489         case VDEC_MSG_RESP_OUTPUT_FLUSHED:
   7490         case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
   7491 
   7492             v4l2_buf_ptr = (v4l2_buffer*)vdec_msg->msgdata.output_frame.client_data;
   7493             omxhdr=omx->m_out_mem_ptr+v4l2_buf_ptr->index;
   7494 
   7495             DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) PicType(%u) Flags (0x%x) FillLen(%u) Crop: L(%u) T(%u) R(%u) B(%u)",
   7496                     omxhdr, (long long)vdec_msg->msgdata.output_frame.time_stamp,
   7497                     vdec_msg->msgdata.output_frame.pic_type, v4l2_buf_ptr->flags,
   7498                     (unsigned int)vdec_msg->msgdata.output_frame.len,
   7499                     vdec_msg->msgdata.output_frame.framesize.left,
   7500                     vdec_msg->msgdata.output_frame.framesize.top,
   7501                     vdec_msg->msgdata.output_frame.framesize.right,
   7502                     vdec_msg->msgdata.output_frame.framesize.bottom);
   7503 
   7504             if (omxhdr && omxhdr->pOutputPortPrivate &&
   7505                     ((omxhdr - omx->m_out_mem_ptr) < (int)omx->drv_ctx.op_buf.actualcount) &&
   7506                     (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
   7507                       - omx->drv_ctx.ptr_respbuffer) < (int)omx->drv_ctx.op_buf.actualcount)) {
   7508 
   7509                 if ( vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
   7510                     omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
   7511                     omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
   7512                     omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
   7513                     omxhdr->nFlags = 0;
   7514 
   7515                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS) {
   7516                         omxhdr->nFlags |= OMX_BUFFERFLAG_EOS;
   7517                         //rc = -1;
   7518                     }
   7519                     if (omxhdr->nFilledLen) {
   7520                         omxhdr->nFlags |= OMX_BUFFERFLAG_ENDOFFRAME;
   7521                     }
   7522                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME || v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_IDRFRAME) {
   7523                         omxhdr->nFlags |= OMX_BUFFERFLAG_SYNCFRAME;
   7524                     } else {
   7525                         omxhdr->nFlags &= ~OMX_BUFFERFLAG_SYNCFRAME;
   7526                     }
   7527                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOSEQ) {
   7528                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7529                     }
   7530                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) {
   7531                         omxhdr->nFlags |= OMX_BUFFERFLAG_DECODEONLY;
   7532                     }
   7533 
   7534                     if (v4l2_buf_ptr->flags & V4L2_MSM_BUF_FLAG_MBAFF) {
   7535                         omxhdr->nFlags |= QOMX_VIDEO_BUFFERFLAG_MBAFF;
   7536                     }
   7537 
   7538                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY) {
   7539                          omxhdr->nFlags |= OMX_BUFFERFLAG_READONLY;
   7540                          DEBUG_PRINT_LOW("F_B_D: READONLY BUFFER - REFERENCE WITH F/W fd = %d",
   7541                                     omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd);
   7542                     }
   7543 
   7544                     if (omx->dynamic_buf_mode && !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_READONLY)) {
   7545                         omx->buf_ref_remove(omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].pmem_fd,
   7546                             omxhdr->nOffset);
   7547                     }
   7548                     if (omxhdr && (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DROP_FRAME) &&
   7549                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_DECODEONLY) &&
   7550                             !(v4l2_buf_ptr->flags & V4L2_QCOM_BUF_FLAG_EOS)) {
   7551                         omx->time_stamp_dts.remove_time_stamp(
   7552                                 omxhdr->nTimeStamp,
   7553                                 (omx->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
   7554                                 ?true:false);
   7555                         omx->post_event ((unsigned long)NULL,(unsigned long)omxhdr,
   7556                                 OMX_COMPONENT_GENERATE_FTB);
   7557                         break;
   7558                     }
   7559                     if (v4l2_buf_ptr->flags & V4L2_QCOM_BUF_DATA_CORRUPT) {
   7560                         omxhdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   7561                     }
   7562                     vdec_msg->msgdata.output_frame.bufferaddr =
   7563                         omx->drv_ctx.ptr_outputbuffer[v4l2_buf_ptr->index].bufferaddr;
   7564 
   7565                     /* Post event if resolution OR crop changed */
   7566                     /* filled length will be changed if resolution changed */
   7567                     /* Crop parameters can be changed even without resolution change */
   7568                     if (omxhdr->nFilledLen
   7569                         && ((omx->prev_n_filled_len != omxhdr->nFilledLen)
   7570                         || (omx->drv_ctx.frame_size.left != vdec_msg->msgdata.output_frame.framesize.left)
   7571                         || (omx->drv_ctx.frame_size.top != vdec_msg->msgdata.output_frame.framesize.top)
   7572                         || (omx->drv_ctx.frame_size.right != vdec_msg->msgdata.output_frame.framesize.right)
   7573                         || (omx->drv_ctx.frame_size.bottom != vdec_msg->msgdata.output_frame.framesize.bottom)
   7574                         || (omx->drv_ctx.video_resolution.frame_width != vdec_msg->msgdata.output_frame.picsize.frame_width)
   7575                         || (omx->drv_ctx.video_resolution.frame_height != vdec_msg->msgdata.output_frame.picsize.frame_height) )) {
   7576 
   7577                         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",
   7578                                 omx->prev_n_filled_len,
   7579                                 omx->drv_ctx.video_resolution.frame_width,
   7580                                 omx->drv_ctx.video_resolution.frame_height,
   7581                                 omx->drv_ctx.frame_size.left, omx->drv_ctx.frame_size.top,
   7582                                 omx->drv_ctx.frame_size.right, omx->drv_ctx.frame_size.bottom,
   7583                                 omxhdr->nFilledLen, vdec_msg->msgdata.output_frame.picsize.frame_width,
   7584                                 vdec_msg->msgdata.output_frame.picsize.frame_height,
   7585                                         vdec_msg->msgdata.output_frame.framesize.left,
   7586                                         vdec_msg->msgdata.output_frame.framesize.top,
   7587                                         vdec_msg->msgdata.output_frame.framesize.right,
   7588                                 vdec_msg->msgdata.output_frame.framesize.bottom);
   7589 
   7590                         omx->drv_ctx.video_resolution.frame_width =
   7591                                 vdec_msg->msgdata.output_frame.picsize.frame_width;
   7592                         omx->drv_ctx.video_resolution.frame_height =
   7593                                 vdec_msg->msgdata.output_frame.picsize.frame_height;
   7594                         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12) {
   7595                             omx->drv_ctx.video_resolution.stride =
   7596                                 VENUS_Y_STRIDE(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_width);
   7597                             omx->drv_ctx.video_resolution.scan_lines =
   7598                                 VENUS_Y_SCANLINES(COLOR_FMT_NV12, omx->drv_ctx.video_resolution.frame_height);
   7599                         }
   7600                         memcpy(&omx->drv_ctx.frame_size,
   7601                                 &vdec_msg->msgdata.output_frame.framesize,
   7602                                 sizeof(struct vdec_framesize));
   7603 
   7604                         omx->post_event(OMX_CORE_OUTPUT_PORT_INDEX,
   7605                                 OMX_IndexConfigCommonOutputCrop,
   7606                                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   7607                         }
   7608 
   7609                     if (omxhdr->nFilledLen)
   7610                         omx->prev_n_filled_len = omxhdr->nFilledLen;
   7611 
   7612                     output_respbuf = (struct vdec_output_frameinfo *)\
   7613                              omxhdr->pOutputPortPrivate;
   7614                     output_respbuf->len = vdec_msg->msgdata.output_frame.len;
   7615                     output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
   7616                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_KEYFRAME) {
   7617                         output_respbuf->pic_type = PICTURE_TYPE_I;
   7618                     }
   7619                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_PFRAME) {
   7620                         output_respbuf->pic_type = PICTURE_TYPE_P;
   7621                     }
   7622                     if (v4l2_buf_ptr->flags & V4L2_BUF_FLAG_BFRAME) {
   7623                         output_respbuf->pic_type = PICTURE_TYPE_B;
   7624                     }
   7625 
   7626                     if (omx->output_use_buffer)
   7627                         memcpy ( omxhdr->pBuffer, (void *)
   7628                                 ((unsigned long)vdec_msg->msgdata.output_frame.bufferaddr +
   7629                                  (unsigned long)vdec_msg->msgdata.output_frame.offset),
   7630                                 vdec_msg->msgdata.output_frame.len);
   7631                 } else {
   7632                     DEBUG_PRINT_ERROR("Invalid filled length = %u, buffer size = %u, prev_length = %u",
   7633                             (unsigned int)vdec_msg->msgdata.output_frame.len,
   7634                             omxhdr->nAllocLen, omx->prev_n_filled_len);
   7635                     omxhdr->nFilledLen = 0;
   7636                 }
   7637 
   7638                 omx->post_event ((unsigned long)omxhdr, vdec_msg->status_code,
   7639                         OMX_COMPONENT_GENERATE_FBD);
   7640 
   7641             } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS) {
   7642                 omx->post_event ((unsigned long)NULL, vdec_msg->status_code,
   7643                         OMX_COMPONENT_GENERATE_EOS_DONE);
   7644             } else {
   7645                 omx->post_event ((unsigned int)NULL, vdec_msg->status_code,
   7646                         OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
   7647             }
   7648             break;
   7649         case VDEC_MSG_EVT_CONFIG_CHANGED:
   7650             DEBUG_PRINT_HIGH("Port settings changed");
   7651             omx->post_event (OMX_CORE_OUTPUT_PORT_INDEX, OMX_IndexParamPortDefinition,
   7652                     OMX_COMPONENT_GENERATE_PORT_RECONFIG);
   7653             break;
   7654         default:
   7655             break;
   7656     }
   7657     return rc;
   7658 }
   7659 
   7660 OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
   7661         OMX_HANDLETYPE hComp,
   7662         OMX_BUFFERHEADERTYPE *buffer
   7663         )
   7664 {
   7665     unsigned address,p2,id;
   7666     DEBUG_PRINT_LOW("Empty this arbitrary");
   7667 
   7668     if (buffer == NULL) {
   7669         return OMX_ErrorBadParameter;
   7670     }
   7671     DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
   7672     DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %u, timestamp %lld",
   7673             (unsigned int)buffer->nFilledLen, (unsigned int)buffer->nFlags, buffer->nTimeStamp);
   7674 
   7675     /* return zero length and not an EOS buffer */
   7676     /* return buffer if input flush in progress */
   7677     if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
   7678                 ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
   7679         DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
   7680         m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
   7681         return OMX_ErrorNone;
   7682     }
   7683 
   7684     if (psource_frame == NULL) {
   7685         DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %lld",buffer,buffer->nTimeStamp);
   7686         psource_frame = buffer;
   7687         DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
   7688         push_input_buffer (hComp);
   7689     } else {
   7690         DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
   7691         if (!m_input_pending_q.insert_entry((unsigned long)buffer, (unsigned)NULL,
   7692                     (unsigned)NULL)) {
   7693             return OMX_ErrorBadParameter;
   7694         }
   7695     }
   7696 
   7697     if (codec_config_flag && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
   7698         codec_config_flag = false;
   7699     }
   7700     return OMX_ErrorNone;
   7701 }
   7702 
   7703 OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
   7704 {
   7705     unsigned long address,p2,id;
   7706     OMX_ERRORTYPE ret = OMX_ErrorNone;
   7707 
   7708     if (pdest_frame == NULL || psource_frame == NULL) {
   7709         /*Check if we have a destination buffer*/
   7710         if (pdest_frame == NULL) {
   7711             DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
   7712             if (m_input_free_q.m_size) {
   7713                 m_input_free_q.pop_entry(&address,&p2,&id);
   7714                 pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
   7715                 pdest_frame->nFilledLen = 0;
   7716                 pdest_frame->nTimeStamp = LLONG_MAX;
   7717                 DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
   7718             }
   7719         }
   7720 
   7721         /*Check if we have a destination buffer*/
   7722         if (psource_frame == NULL) {
   7723             DEBUG_PRINT_LOW("Get a source buffer from the queue");
   7724             if (m_input_pending_q.m_size) {
   7725                 m_input_pending_q.pop_entry(&address,&p2,&id);
   7726                 psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   7727                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   7728                         psource_frame->nTimeStamp);
   7729                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   7730                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   7731 
   7732             }
   7733         }
   7734 
   7735     }
   7736 
   7737     while ((pdest_frame != NULL) && (psource_frame != NULL)) {
   7738         switch (codec_type_parse) {
   7739             case CODEC_TYPE_MPEG4:
   7740             case CODEC_TYPE_H263:
   7741             case CODEC_TYPE_MPEG2:
   7742                 ret =  push_input_sc_codec(hComp);
   7743                 break;
   7744             case CODEC_TYPE_H264:
   7745                 ret = push_input_h264(hComp);
   7746                 break;
   7747             case CODEC_TYPE_HEVC:
   7748                 ret = push_input_hevc(hComp);
   7749                 break;
   7750             case CODEC_TYPE_VC1:
   7751                 ret = push_input_vc1(hComp);
   7752                 break;
   7753             default:
   7754                 break;
   7755         }
   7756         if (ret != OMX_ErrorNone) {
   7757             DEBUG_PRINT_ERROR("Pushing input Buffer Failed");
   7758             omx_report_error ();
   7759             break;
   7760         }
   7761     }
   7762 
   7763     return ret;
   7764 }
   7765 
   7766 OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
   7767 {
   7768     OMX_U32 partial_frame = 1;
   7769     OMX_BOOL generate_ebd = OMX_TRUE;
   7770     unsigned long address = 0, p2 = 0, id = 0;
   7771 
   7772     DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %lld",
   7773             psource_frame,psource_frame->nTimeStamp);
   7774     if (m_frame_parser.parse_sc_frame(psource_frame,
   7775                 pdest_frame,&partial_frame) == -1) {
   7776         DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   7777         return OMX_ErrorBadParameter;
   7778     }
   7779 
   7780     if (partial_frame == 0) {
   7781         DEBUG_PRINT_LOW("Frame size %u source %p frame count %d",
   7782                 (unsigned int)pdest_frame->nFilledLen,psource_frame,frame_count);
   7783 
   7784 
   7785         DEBUG_PRINT_LOW("TimeStamp updated %lld", pdest_frame->nTimeStamp);
   7786         /*First Parsed buffer will have only header Hence skip*/
   7787         if (frame_count == 0) {
   7788             DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
   7789 
   7790             if (codec_type_parse == CODEC_TYPE_MPEG4 ||
   7791                     codec_type_parse == CODEC_TYPE_DIVX) {
   7792                 mp4StreamType psBits;
   7793                 psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
   7794                 psBits.numBytes = pdest_frame->nFilledLen;
   7795                 mp4_headerparser.parseHeader(&psBits);
   7796             }
   7797 
   7798             frame_count++;
   7799         } else {
   7800             pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   7801             if (pdest_frame->nFilledLen) {
   7802                 /*Push the frame to the Decoder*/
   7803                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   7804                     return OMX_ErrorBadParameter;
   7805                 }
   7806                 frame_count++;
   7807                 pdest_frame = NULL;
   7808 
   7809                 if (m_input_free_q.m_size) {
   7810                     m_input_free_q.pop_entry(&address,&p2,&id);
   7811                     pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   7812                     pdest_frame->nFilledLen = 0;
   7813                 }
   7814             } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
   7815                 DEBUG_PRINT_ERROR("Zero len buffer return back to POOL");
   7816                 m_input_free_q.insert_entry((unsigned long) pdest_frame, (unsigned)NULL,
   7817                         (unsigned)NULL);
   7818                 pdest_frame = NULL;
   7819             }
   7820         }
   7821     } else {
   7822         DEBUG_PRINT_LOW("Not a Complete Frame %u", (unsigned int)pdest_frame->nFilledLen);
   7823         /*Check if Destination Buffer is full*/
   7824         if (pdest_frame->nAllocLen ==
   7825                 pdest_frame->nFilledLen + pdest_frame->nOffset) {
   7826             DEBUG_PRINT_ERROR("ERROR:Frame Not found though Destination Filled");
   7827             return OMX_ErrorStreamCorrupt;
   7828         }
   7829     }
   7830 
   7831     if (psource_frame->nFilledLen == 0) {
   7832         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   7833             if (pdest_frame) {
   7834                 pdest_frame->nFlags |= psource_frame->nFlags;
   7835                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %lld",
   7836                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   7837                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   7838                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   7839                 /*Push the frame to the Decoder*/
   7840                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   7841                     return OMX_ErrorBadParameter;
   7842                 }
   7843                 frame_count++;
   7844                 pdest_frame = NULL;
   7845             } else {
   7846                 DEBUG_PRINT_LOW("Last frame in else dest addr") ;
   7847                 generate_ebd = OMX_FALSE;
   7848             }
   7849         }
   7850         if (generate_ebd) {
   7851             DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
   7852             m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   7853             psource_frame = NULL;
   7854 
   7855             if (m_input_pending_q.m_size) {
   7856                 DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   7857                 m_input_pending_q.pop_entry(&address,&p2,&id);
   7858                 psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   7859                 DEBUG_PRINT_LOW("Next source Buffer %p time stamp %lld",psource_frame,
   7860                         psource_frame->nTimeStamp);
   7861                 DEBUG_PRINT_LOW("Next source Buffer flag %u length %u",
   7862                         (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   7863             }
   7864         }
   7865     }
   7866     return OMX_ErrorNone;
   7867 }
   7868 
   7869 OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
   7870 {
   7871     OMX_U32 partial_frame = 1;
   7872     unsigned long address = 0, p2 = 0, id = 0;
   7873     OMX_BOOL isNewFrame = OMX_FALSE;
   7874     OMX_BOOL generate_ebd = OMX_TRUE;
   7875 
   7876     if (h264_scratch.pBuffer == NULL) {
   7877         DEBUG_PRINT_ERROR("ERROR:H.264 Scratch Buffer not allocated");
   7878         return OMX_ErrorBadParameter;
   7879     }
   7880     DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %u "
   7881             "look_ahead_nal %d", (unsigned int)h264_scratch.nFilledLen, look_ahead_nal);
   7882     DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %u",(unsigned int)pdest_frame->nFilledLen);
   7883     if (h264_scratch.nFilledLen && look_ahead_nal) {
   7884         look_ahead_nal = false;
   7885         if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7886                 h264_scratch.nFilledLen) {
   7887             memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7888                     h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7889             pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7890             DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
   7891             h264_scratch.nFilledLen = 0;
   7892         } else {
   7893             DEBUG_PRINT_ERROR("Error:1: Destination buffer overflow for H264");
   7894             return OMX_ErrorBadParameter;
   7895         }
   7896     }
   7897 
   7898     /* If an empty input is queued with EOS, do not coalesce with the destination-frame yet, as this may result
   7899        in EOS flag getting associated with the destination
   7900     */
   7901     if (!psource_frame->nFilledLen && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) &&
   7902             pdest_frame->nFilledLen) {
   7903         DEBUG_PRINT_HIGH("delay ETB for 'empty buffer with EOS'");
   7904         generate_ebd = OMX_FALSE;
   7905     }
   7906 
   7907     if (nal_length == 0) {
   7908         DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
   7909         if (m_frame_parser.parse_sc_frame(psource_frame,
   7910                     &h264_scratch,&partial_frame) == -1) {
   7911             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   7912             return OMX_ErrorBadParameter;
   7913         }
   7914     } else {
   7915         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
   7916         if (m_frame_parser.parse_h264_nallength(psource_frame,
   7917                     &h264_scratch,&partial_frame) == -1) {
   7918             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   7919             return OMX_ErrorBadParameter;
   7920         }
   7921     }
   7922 
   7923     if (partial_frame == 0) {
   7924         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   7925             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   7926             nal_count++;
   7927             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   7928             h264_scratch.nFlags = psource_frame->nFlags;
   7929         } else {
   7930             DEBUG_PRINT_LOW("Parsed New NAL Length = %u",(unsigned int)h264_scratch.nFilledLen);
   7931             if (h264_scratch.nFilledLen) {
   7932                 h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
   7933                         NALU_TYPE_SPS);
   7934 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   7935                 if (client_extradata & OMX_TIMEINFO_EXTRADATA)
   7936                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   7937                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   7938                 else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   7939                     // If timeinfo is present frame info from SEI is already processed
   7940                     h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
   7941                             h264_scratch.nFilledLen, NALU_TYPE_SEI);
   7942 #endif
   7943                 m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   7944                 nal_count++;
   7945                 if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
   7946                     pdest_frame->nTimeStamp = h264_last_au_ts;
   7947                     pdest_frame->nFlags = h264_last_au_flags;
   7948 #ifdef PANSCAN_HDLR
   7949                     if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
   7950                         h264_parser->update_panscan_data(h264_last_au_ts);
   7951 #endif
   7952                 }
   7953                 if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
   7954                         m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
   7955                     h264_last_au_ts = h264_scratch.nTimeStamp;
   7956                     h264_last_au_flags = h264_scratch.nFlags;
   7957 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   7958                     if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   7959                         OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
   7960                         if (!VALID_TS(h264_last_au_ts))
   7961                             h264_last_au_ts = ts_in_sei;
   7962                     }
   7963 #endif
   7964                 } else
   7965                     h264_last_au_ts = LLONG_MAX;
   7966             }
   7967 
   7968             if (!isNewFrame) {
   7969                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7970                         h264_scratch.nFilledLen) {
   7971                     DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %u",
   7972                             (unsigned int)h264_scratch.nFilledLen);
   7973                     memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7974                             h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7975                     pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7976                     if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
   7977                         pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
   7978                     h264_scratch.nFilledLen = 0;
   7979                 } else {
   7980                     DEBUG_PRINT_LOW("Error:2: Destination buffer overflow for H264");
   7981                     return OMX_ErrorBadParameter;
   7982                 }
   7983             } else if(h264_scratch.nFilledLen) {
   7984                 look_ahead_nal = true;
   7985                 DEBUG_PRINT_LOW("Frame Found start Decoding Size =%u TimeStamp = %llu",
   7986                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   7987                 DEBUG_PRINT_LOW("Found a frame size = %u number = %d",
   7988                         (unsigned int)pdest_frame->nFilledLen,frame_count++);
   7989 
   7990                 if (pdest_frame->nFilledLen == 0) {
   7991                     DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
   7992                     look_ahead_nal = false;
   7993                     if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   7994                             h264_scratch.nFilledLen) {
   7995                         memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   7996                                 h264_scratch.pBuffer,h264_scratch.nFilledLen);
   7997                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   7998                         h264_scratch.nFilledLen = 0;
   7999                     } else {
   8000                         DEBUG_PRINT_ERROR("Error:3: Destination buffer overflow for H264");
   8001                         return OMX_ErrorBadParameter;
   8002                     }
   8003                 } else {
   8004                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   8005                         DEBUG_PRINT_LOW("Reset the EOS Flag");
   8006                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   8007                     }
   8008                     /*Push the frame to the Decoder*/
   8009                     if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8010                         return OMX_ErrorBadParameter;
   8011                     }
   8012                     //frame_count++;
   8013                     pdest_frame = NULL;
   8014                     if (m_input_free_q.m_size) {
   8015                         m_input_free_q.pop_entry(&address,&p2,&id);
   8016                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   8017                         DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
   8018                         pdest_frame->nFilledLen = 0;
   8019                         pdest_frame->nFlags = 0;
   8020                         pdest_frame->nTimeStamp = LLONG_MAX;
   8021                     }
   8022                 }
   8023             }
   8024         }
   8025     } else {
   8026         DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %u", (unsigned int)pdest_frame->nFilledLen);
   8027         /*Check if Destination Buffer is full*/
   8028         if (h264_scratch.nAllocLen ==
   8029                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   8030             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   8031             return OMX_ErrorStreamCorrupt;
   8032         }
   8033     }
   8034 
   8035     if (!psource_frame->nFilledLen) {
   8036         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
   8037 
   8038         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   8039             if (pdest_frame) {
   8040                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   8041                 if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
   8042                         h264_scratch.nFilledLen) {
   8043                     if(pdest_frame->nFilledLen == 0) {
   8044                         /* No residual frame from before, send whatever
   8045                          * we have left */
   8046                         memcpy((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8047                                 h264_scratch.pBuffer, h264_scratch.nFilledLen);
   8048                         pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8049                         h264_scratch.nFilledLen = 0;
   8050                         pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   8051                     } else {
   8052                         m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
   8053                         if(!isNewFrame) {
   8054                             /* Have a residual frame, but we know that the
   8055                              * AU in this frame is belonging to whatever
   8056                              * frame we had left over.  So append it */
   8057                              memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
   8058                                      h264_scratch.pBuffer,h264_scratch.nFilledLen);
   8059                              pdest_frame->nFilledLen += h264_scratch.nFilledLen;
   8060                              h264_scratch.nFilledLen = 0;
   8061                              if (h264_last_au_ts != LLONG_MAX)
   8062                              pdest_frame->nTimeStamp = h264_last_au_ts;
   8063                         } else {
   8064                             /* Completely new frame, let's just push what
   8065                              * we have now.  The resulting EBD would trigger
   8066                              * another push */
   8067                             generate_ebd = OMX_FALSE;
   8068                             pdest_frame->nTimeStamp = h264_last_au_ts;
   8069                             h264_last_au_ts = h264_scratch.nTimeStamp;
   8070                         }
   8071                     }
   8072                 } else {
   8073                     DEBUG_PRINT_ERROR("ERROR:4: Destination buffer overflow for H264");
   8074                     return OMX_ErrorBadParameter;
   8075                 }
   8076 
   8077                 /* Iff we coalesced two buffers, inherit the flags of both bufs */
   8078                 if(generate_ebd == OMX_TRUE) {
   8079                      pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   8080                 }
   8081 
   8082                 DEBUG_PRINT_LOW("pdest_frame->nFilledLen =%u TimeStamp = %llu",
   8083                         (unsigned int)pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
   8084                 DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
   8085 #ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
   8086                 if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
   8087                     OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
   8088                     if (!VALID_TS(pdest_frame->nTimeStamp))
   8089                         pdest_frame->nTimeStamp = ts_in_sei;
   8090                 }
   8091 #endif
   8092                 /*Push the frame to the Decoder*/
   8093                 if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
   8094                     return OMX_ErrorBadParameter;
   8095                 }
   8096                 frame_count++;
   8097                 pdest_frame = NULL;
   8098             } else {
   8099                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   8100                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   8101                 generate_ebd = OMX_FALSE;
   8102             }
   8103         }
   8104     }
   8105     if (generate_ebd && !psource_frame->nFilledLen) {
   8106         m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
   8107         psource_frame = NULL;
   8108         if (m_input_pending_q.m_size) {
   8109             DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
   8110             m_input_pending_q.pop_entry(&address,&p2,&id);
   8111             psource_frame = (OMX_BUFFERHEADERTYPE *) address;
   8112             DEBUG_PRINT_LOW("Next source Buffer flag %u src length %u",
   8113                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen);
   8114         }
   8115     }
   8116     return OMX_ErrorNone;
   8117 }
   8118 
   8119 OMX_ERRORTYPE copy_buffer(OMX_BUFFERHEADERTYPE* pDst, OMX_BUFFERHEADERTYPE* pSrc)
   8120 {
   8121     OMX_ERRORTYPE rc = OMX_ErrorNone;
   8122     if ((pDst->nAllocLen - pDst->nFilledLen) >= pSrc->nFilledLen) {
   8123         memcpy((pDst->pBuffer + pDst->nFilledLen), pSrc->pBuffer, pSrc->nFilledLen);
   8124         if (pDst->nTimeStamp == LLONG_MAX) {
   8125             pDst->nTimeStamp = pSrc->nTimeStamp;
   8126             DEBUG_PRINT_LOW("Assign Dst nTimeStamp = %lld", pDst->nTimeStamp);
   8127         }
   8128         pDst->nFilledLen += pSrc->nFilledLen;
   8129         pSrc->nFilledLen = 0;
   8130     } else {
   8131         DEBUG_PRINT_ERROR("Error: Destination buffer overflow");
   8132         rc = OMX_ErrorBadParameter;
   8133     }
   8134     return rc;
   8135 }
   8136 
   8137 OMX_ERRORTYPE omx_vdec::push_input_hevc(OMX_HANDLETYPE hComp)
   8138 {
   8139     OMX_U32 partial_frame = 1;
   8140     unsigned long address,p2,id;
   8141     OMX_BOOL isNewFrame = OMX_FALSE;
   8142     OMX_BOOL generate_ebd = OMX_TRUE;
   8143     OMX_ERRORTYPE rc = OMX_ErrorNone;
   8144     if (h264_scratch.pBuffer == NULL) {
   8145         DEBUG_PRINT_ERROR("ERROR:Hevc Scratch Buffer not allocated");
   8146         return OMX_ErrorBadParameter;
   8147     }
   8148 
   8149     DEBUG_PRINT_LOW("h264_scratch.nFilledLen %u has look_ahead_nal %d \
   8150             pdest_frame nFilledLen %u nTimeStamp %lld",
   8151             (unsigned int)h264_scratch.nFilledLen, look_ahead_nal, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   8152 
   8153     if (h264_scratch.nFilledLen && look_ahead_nal) {
   8154         look_ahead_nal = false;
   8155         rc = copy_buffer(pdest_frame, &h264_scratch);
   8156         if (rc != OMX_ErrorNone) {
   8157             return rc;
   8158         }
   8159     }
   8160 
   8161     if (nal_length == 0) {
   8162         if (m_frame_parser.parse_sc_frame(psource_frame,
   8163                     &h264_scratch,&partial_frame) == -1) {
   8164             DEBUG_PRINT_ERROR("Error In Parsing Return Error");
   8165             return OMX_ErrorBadParameter;
   8166         }
   8167     } else {
   8168         DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d",nal_length);
   8169         if (m_frame_parser.parse_h264_nallength(psource_frame,
   8170                     &h264_scratch,&partial_frame) == -1) {
   8171             DEBUG_PRINT_ERROR("Error In Parsing NAL size, Return Error");
   8172             return OMX_ErrorBadParameter;
   8173         }
   8174     }
   8175 
   8176     if (partial_frame == 0) {
   8177         if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
   8178             DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
   8179             nal_count++;
   8180             h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
   8181             h264_scratch.nFlags = psource_frame->nFlags;
   8182         } else {
   8183             DEBUG_PRINT_LOW("Parsed New NAL Length = %u", (unsigned int)h264_scratch.nFilledLen);
   8184             if (h264_scratch.nFilledLen) {
   8185                 m_hevc_utils.isNewFrame(&h264_scratch, 0, isNewFrame);
   8186                 nal_count++;
   8187             }
   8188 
   8189             if (!isNewFrame) {
   8190                 DEBUG_PRINT_LOW("Not a new frame, copy h264_scratch nFilledLen %u \
   8191                         nTimestamp %lld, pdest_frame nFilledLen %u nTimestamp %lld",
   8192                         (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp,
   8193                         (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   8194                 rc = copy_buffer(pdest_frame, &h264_scratch);
   8195                 if (rc != OMX_ErrorNone) {
   8196                     return rc;
   8197                 }
   8198             } else {
   8199                 look_ahead_nal = true;
   8200                 if (pdest_frame->nFilledLen == 0) {
   8201                     look_ahead_nal = false;
   8202                     DEBUG_PRINT_LOW("dest nation buffer empty, copy scratch buffer");
   8203                     rc = copy_buffer(pdest_frame, &h264_scratch);
   8204                     if (rc != OMX_ErrorNone) {
   8205                         return OMX_ErrorBadParameter;
   8206                     }
   8207                 } else {
   8208                     if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
   8209                         pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
   8210                     }
   8211                     DEBUG_PRINT_LOW("FrameDetected # %d pdest_frame nFilledLen %u \
   8212                             nTimeStamp %lld, look_ahead_nal in h264_scratch \
   8213                             nFilledLen %u nTimeStamp %lld",
   8214                             frame_count++, (unsigned int)pdest_frame->nFilledLen,
   8215                             pdest_frame->nTimeStamp, (unsigned int)h264_scratch.nFilledLen,
   8216                             h264_scratch.nTimeStamp);
   8217                     if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   8218                         return OMX_ErrorBadParameter;
   8219                     }
   8220                     pdest_frame = NULL;
   8221                     if (m_input_free_q.m_size) {
   8222                         m_input_free_q.pop_entry(&address, &p2, &id);
   8223                         pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
   8224                         DEBUG_PRINT_LOW("pop the next pdest_buffer %p", pdest_frame);
   8225                         pdest_frame->nFilledLen = 0;
   8226                         pdest_frame->nFlags = 0;
   8227                         pdest_frame->nTimeStamp = LLONG_MAX;
   8228                     }
   8229                 }
   8230             }
   8231         }
   8232     } else {
   8233         DEBUG_PRINT_LOW("psource_frame is partial nFilledLen %u nTimeStamp %lld, \
   8234                 pdest_frame nFilledLen %u nTimeStamp %lld, h264_scratch \
   8235                 nFilledLen %u nTimeStamp %lld",
   8236                 (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp,
   8237                 (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp,
   8238                 (unsigned int)h264_scratch.nFilledLen, h264_scratch.nTimeStamp);
   8239 
   8240         if (h264_scratch.nAllocLen ==
   8241                 h264_scratch.nFilledLen + h264_scratch.nOffset) {
   8242             DEBUG_PRINT_ERROR("ERROR: Frame Not found though Destination Filled");
   8243             return OMX_ErrorStreamCorrupt;
   8244         }
   8245     }
   8246 
   8247     if (!psource_frame->nFilledLen) {
   8248         DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client", psource_frame);
   8249         if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
   8250             if (pdest_frame) {
   8251                 DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
   8252                 rc = copy_buffer(pdest_frame, &h264_scratch);
   8253                 if ( rc != OMX_ErrorNone ) {
   8254                     return rc;
   8255                 }
   8256                 pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
   8257                 pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
   8258                 DEBUG_PRINT_LOW("Push EOS frame number:%d nFilledLen =%u TimeStamp = %lld",
   8259                         frame_count, (unsigned int)pdest_frame->nFilledLen, pdest_frame->nTimeStamp);
   8260                 if (empty_this_buffer_proxy(hComp, pdest_frame) != OMX_ErrorNone) {
   8261                     return OMX_ErrorBadParameter;
   8262                 }
   8263                 frame_count++;
   8264                 pdest_frame = NULL;
   8265             } else {
   8266                 DEBUG_PRINT_LOW("Last frame in else dest addr %p size %u",
   8267                         pdest_frame, (unsigned int)h264_scratch.nFilledLen);
   8268                 generate_ebd = OMX_FALSE;
   8269             }
   8270         }
   8271     }
   8272 
   8273     if (generate_ebd && !psource_frame->nFilledLen) {
   8274         m_cb.EmptyBufferDone (hComp, m_app_data, psource_frame);
   8275         psource_frame = NULL;
   8276         if (m_input_pending_q.m_size) {
   8277             m_input_pending_q.pop_entry(&address, &p2, &id);
   8278             psource_frame = (OMX_BUFFERHEADERTYPE *)address;
   8279             DEBUG_PRINT_LOW("Next source Buffer flag %u nFilledLen %u, nTimeStamp %lld",
   8280                     (unsigned int)psource_frame->nFlags, (unsigned int)psource_frame->nFilledLen, psource_frame->nTimeStamp);
   8281         }
   8282     }
   8283     return OMX_ErrorNone;
   8284 }
   8285 
   8286 OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
   8287 {
   8288     OMX_U8 *buf, *pdest;
   8289     OMX_U32 partial_frame = 1;
   8290     OMX_U32 buf_len, dest_len;
   8291 
   8292     if (first_frame == 0) {
   8293         first_frame = 1;
   8294         DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
   8295         if (!m_vendor_config.pData) {
   8296             DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
   8297             buf = psource_frame->pBuffer;
   8298             buf_len = psource_frame->nFilledLen;
   8299 
   8300             if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
   8301                     VC1_SP_MP_START_CODE) {
   8302                 m_vc1_profile = VC1_SP_MP_RCV;
   8303             } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
   8304                 m_vc1_profile = VC1_AP;
   8305             } else {
   8306                 DEBUG_PRINT_ERROR("Invalid sequence layer in first buffer");
   8307                 return OMX_ErrorStreamCorrupt;
   8308             }
   8309         } else {
   8310             pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
   8311                 pdest_frame->nOffset;
   8312             dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
   8313                     pdest_frame->nOffset);
   8314 
   8315             if (dest_len < m_vendor_config.nDataSize) {
   8316                 DEBUG_PRINT_ERROR("Destination buffer full");
   8317                 return OMX_ErrorBadParameter;
   8318             } else {
   8319                 memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
   8320                 pdest_frame->nFilledLen += m_vendor_config.nDataSize;
   8321             }
   8322         }
   8323     }
   8324 
   8325     switch (m_vc1_profile) {
   8326         case VC1_AP:
   8327             DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
   8328             if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
   8329                 DEBUG_PRINT_ERROR("Error In Parsing VC1 AP start code");
   8330                 return OMX_ErrorBadParameter;
   8331             }
   8332             break;
   8333 
   8334         case VC1_SP_MP_RCV:
   8335         default:
   8336             DEBUG_PRINT_ERROR("Unsupported VC1 profile in ArbitraryBytes Mode");
   8337             return OMX_ErrorBadParameter;
   8338     }
   8339     return OMX_ErrorNone;
   8340 }
   8341 
   8342 #ifndef USE_ION
   8343 bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
   8344         OMX_U32 alignment)
   8345 {
   8346     struct pmem_allocation allocation;
   8347     allocation.size = buffer_size;
   8348     allocation.align = clip2(alignment);
   8349     if (allocation.align < 4096) {
   8350         allocation.align = 4096;
   8351     }
   8352     if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
   8353         DEBUG_PRINT_ERROR("Aligment(%u) failed with pmem driver Sz(%lu)",
   8354                 allocation.align, allocation.size);
   8355         return false;
   8356     }
   8357     return true;
   8358 }
   8359 #endif
   8360 #ifdef USE_ION
   8361 int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
   8362         OMX_U32 alignment, struct ion_allocation_data *alloc_data,
   8363         struct ion_fd_data *fd_data, int flag)
   8364 {
   8365     int fd = -EINVAL;
   8366     int rc = -EINVAL;
   8367     int ion_dev_flag;
   8368     struct vdec_ion ion_buf_info;
   8369     if (!alloc_data || buffer_size <= 0 || !fd_data) {
   8370         DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory");
   8371         return -EINVAL;
   8372     }
   8373     ion_dev_flag = O_RDONLY;
   8374     fd = open (MEM_DEVICE, ion_dev_flag);
   8375     if (fd < 0) {
   8376         DEBUG_PRINT_ERROR("opening ion device failed with fd = %d", fd);
   8377         return fd;
   8378     }
   8379     alloc_data->flags = 0;
   8380     if (!secure_mode && (flag & ION_FLAG_CACHED)) {
   8381         alloc_data->flags |= ION_FLAG_CACHED;
   8382     }
   8383     alloc_data->len = buffer_size;
   8384     alloc_data->align = clip2(alignment);
   8385     if (alloc_data->align < 4096) {
   8386         alloc_data->align = 4096;
   8387     }
   8388     if ((secure_mode) && (flag & ION_SECURE))
   8389         alloc_data->flags |= ION_SECURE;
   8390 
   8391     alloc_data->ION_HEAP_MASK = ION_HEAP(ION_IOMMU_HEAP_ID);
   8392     if (secure_mode && (alloc_data->flags & ION_SECURE))
   8393         alloc_data->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
   8394     rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
   8395     if (rc || !alloc_data->handle) {
   8396         DEBUG_PRINT_ERROR("ION ALLOC memory failed");
   8397         alloc_data->handle = 0;
   8398         close(fd);
   8399         fd = -ENOMEM;
   8400         return fd;
   8401     }
   8402     fd_data->handle = alloc_data->handle;
   8403     rc = ioctl(fd,ION_IOC_MAP,fd_data);
   8404     if (rc) {
   8405         DEBUG_PRINT_ERROR("ION MAP failed ");
   8406         ion_buf_info.ion_alloc_data = *alloc_data;
   8407         ion_buf_info.ion_device_fd = fd;
   8408         ion_buf_info.fd_ion_data = *fd_data;
   8409         free_ion_memory(&ion_buf_info);
   8410         fd_data->fd =-1;
   8411         fd = -ENOMEM;
   8412     }
   8413 
   8414     return fd;
   8415 }
   8416 
   8417 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   8418 {
   8419 
   8420     if (!buf_ion_info) {
   8421         DEBUG_PRINT_ERROR("ION: free called with invalid fd/allocdata");
   8422         return;
   8423     }
   8424     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
   8425                 &buf_ion_info->ion_alloc_data.handle)) {
   8426         DEBUG_PRINT_ERROR("ION: free failed" );
   8427     }
   8428     close(buf_ion_info->ion_device_fd);
   8429     buf_ion_info->ion_device_fd = -1;
   8430     buf_ion_info->ion_alloc_data.handle = 0;
   8431     buf_ion_info->fd_ion_data.fd = -1;
   8432 }
   8433 #endif
   8434 void omx_vdec::free_output_buffer_header()
   8435 {
   8436     DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
   8437     output_use_buffer = false;
   8438     ouput_egl_buffers = false;
   8439 
   8440     if (m_out_mem_ptr) {
   8441         free (m_out_mem_ptr);
   8442         m_out_mem_ptr = NULL;
   8443     }
   8444 
   8445     if (m_platform_list) {
   8446         free(m_platform_list);
   8447         m_platform_list = NULL;
   8448     }
   8449 
   8450     if (drv_ctx.ptr_respbuffer) {
   8451         free (drv_ctx.ptr_respbuffer);
   8452         drv_ctx.ptr_respbuffer = NULL;
   8453     }
   8454     if (drv_ctx.ptr_outputbuffer) {
   8455         free (drv_ctx.ptr_outputbuffer);
   8456         drv_ctx.ptr_outputbuffer = NULL;
   8457     }
   8458 #ifdef USE_ION
   8459     if (drv_ctx.op_buf_ion_info) {
   8460         DEBUG_PRINT_LOW("Free o/p ion context");
   8461         free(drv_ctx.op_buf_ion_info);
   8462         drv_ctx.op_buf_ion_info = NULL;
   8463     }
   8464 #endif
   8465     if (out_dynamic_list) {
   8466         free(out_dynamic_list);
   8467         out_dynamic_list = NULL;
   8468     }
   8469 }
   8470 
   8471 void omx_vdec::free_input_buffer_header()
   8472 {
   8473     input_use_buffer = false;
   8474     if (arbitrary_bytes) {
   8475         if (m_inp_heap_ptr) {
   8476             DEBUG_PRINT_LOW("Free input Heap Pointer");
   8477             free (m_inp_heap_ptr);
   8478             m_inp_heap_ptr = NULL;
   8479         }
   8480 
   8481         if (m_phdr_pmem_ptr) {
   8482             DEBUG_PRINT_LOW("Free input pmem header Pointer");
   8483             free (m_phdr_pmem_ptr);
   8484             m_phdr_pmem_ptr = NULL;
   8485         }
   8486     }
   8487     if (m_inp_mem_ptr) {
   8488         DEBUG_PRINT_LOW("Free input pmem Pointer area");
   8489         free (m_inp_mem_ptr);
   8490         m_inp_mem_ptr = NULL;
   8491     }
   8492     /* We just freed all the buffer headers, every thing in m_input_free_q,
   8493      * m_input_pending_q, pdest_frame, and psource_frame is now invalid */
   8494     while (m_input_free_q.m_size) {
   8495         unsigned long address, p2, id;
   8496         m_input_free_q.pop_entry(&address, &p2, &id);
   8497     }
   8498     while (m_input_pending_q.m_size) {
   8499         unsigned long address, p2, id;
   8500         m_input_pending_q.pop_entry(&address, &p2, &id);
   8501     }
   8502     pdest_frame = NULL;
   8503     psource_frame = NULL;
   8504     if (drv_ctx.ptr_inputbuffer) {
   8505         DEBUG_PRINT_LOW("Free Driver Context pointer");
   8506         free (drv_ctx.ptr_inputbuffer);
   8507         drv_ctx.ptr_inputbuffer = NULL;
   8508     }
   8509 #ifdef USE_ION
   8510     if (drv_ctx.ip_buf_ion_info) {
   8511         DEBUG_PRINT_LOW("Free ion context");
   8512         free(drv_ctx.ip_buf_ion_info);
   8513         drv_ctx.ip_buf_ion_info = NULL;
   8514     }
   8515 #endif
   8516 }
   8517 
   8518 int omx_vdec::stream_off(OMX_U32 port)
   8519 {
   8520     enum v4l2_buf_type btype;
   8521     int rc = 0;
   8522     enum v4l2_ports v4l2_port = OUTPUT_PORT;
   8523 
   8524     if (port == OMX_CORE_INPUT_PORT_INDEX) {
   8525         btype = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8526         v4l2_port = OUTPUT_PORT;
   8527     } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
   8528         btype = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8529         v4l2_port = CAPTURE_PORT;
   8530     } else if (port == OMX_ALL) {
   8531         int rc_input = stream_off(OMX_CORE_INPUT_PORT_INDEX);
   8532         int rc_output = stream_off(OMX_CORE_OUTPUT_PORT_INDEX);
   8533 
   8534         if (!rc_input)
   8535             return rc_input;
   8536         else
   8537             return rc_output;
   8538     }
   8539 
   8540     if (!streaming[v4l2_port]) {
   8541         // already streamed off, warn and move on
   8542         DEBUG_PRINT_HIGH("Warning: Attempting to stream off on %d port,"
   8543                 " which is already streamed off", v4l2_port);
   8544         return 0;
   8545     }
   8546 
   8547     DEBUG_PRINT_HIGH("Streaming off %d port", v4l2_port);
   8548 
   8549     rc = ioctl(drv_ctx.video_driver_fd, VIDIOC_STREAMOFF, &btype);
   8550     if (rc) {
   8551         /*TODO: How to handle this case */
   8552         DEBUG_PRINT_ERROR("Failed to call streamoff on %d Port", v4l2_port);
   8553     } else {
   8554         streaming[v4l2_port] = false;
   8555     }
   8556 
   8557     return rc;
   8558 }
   8559 
   8560 OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
   8561 {
   8562     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8563     struct v4l2_requestbuffers bufreq;
   8564     unsigned int buf_size = 0, extra_data_size = 0, default_extra_data_size = 0;
   8565     unsigned int final_extra_data_size = 0;
   8566     struct v4l2_format fmt;
   8567     int ret = 0;
   8568     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   8569             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   8570     bufreq.memory = V4L2_MEMORY_USERPTR;
   8571     bufreq.count = 1;
   8572     if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   8573         bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8574         fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8575         fmt.fmt.pix_mp.pixelformat = output_capability;
   8576     } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   8577         bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8578         fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8579         fmt.fmt.pix_mp.pixelformat = capture_capability;
   8580     } else {
   8581         eRet = OMX_ErrorBadParameter;
   8582     }
   8583     if (eRet==OMX_ErrorNone) {
   8584         ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   8585     }
   8586     if (ret) {
   8587         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   8588         /*TODO: How to handle this case */
   8589         eRet = OMX_ErrorInsufficientResources;
   8590         return eRet;
   8591     } else {
   8592         buffer_prop->actualcount = bufreq.count;
   8593         buffer_prop->mincount = bufreq.count;
   8594         DEBUG_PRINT_HIGH("Count = %d",bufreq.count);
   8595     }
   8596     DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%u)",
   8597             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   8598 
   8599     fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   8600     fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   8601 
   8602     ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   8603 
   8604     update_resolution(fmt.fmt.pix_mp.width,
   8605             fmt.fmt.pix_mp.height,
   8606             fmt.fmt.pix_mp.plane_fmt[0].bytesperline,
   8607             fmt.fmt.pix_mp.plane_fmt[0].reserved[0]);
   8608     if (fmt.type == V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE)
   8609         drv_ctx.num_planes = fmt.fmt.pix_mp.num_planes;
   8610     DEBUG_PRINT_HIGH("Buffer Size = %d",fmt.fmt.pix_mp.plane_fmt[0].sizeimage);
   8611 
   8612     if (ret) {
   8613         /*TODO: How to handle this case */
   8614         DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
   8615         eRet = OMX_ErrorInsufficientResources;
   8616     } else {
   8617         int extra_idx = 0;
   8618 
   8619         eRet = is_video_session_supported();
   8620         if (eRet)
   8621             return eRet;
   8622 
   8623         buffer_prop->buffer_size = fmt.fmt.pix_mp.plane_fmt[0].sizeimage;
   8624         buf_size = buffer_prop->buffer_size;
   8625         extra_idx = EXTRADATA_IDX(drv_ctx.num_planes);
   8626         if (extra_idx && (extra_idx < VIDEO_MAX_PLANES)) {
   8627             extra_data_size =  fmt.fmt.pix_mp.plane_fmt[extra_idx].sizeimage;
   8628         } else if (extra_idx >= VIDEO_MAX_PLANES) {
   8629             DEBUG_PRINT_ERROR("Extradata index is more than allowed: %d", extra_idx);
   8630             return OMX_ErrorBadParameter;
   8631         }
   8632 
   8633         default_extra_data_size = VENUS_EXTRADATA_SIZE(
   8634                 drv_ctx.video_resolution.frame_height,
   8635                 drv_ctx.video_resolution.frame_width);
   8636         final_extra_data_size = extra_data_size > default_extra_data_size ?
   8637             extra_data_size : default_extra_data_size;
   8638 
   8639         final_extra_data_size = (final_extra_data_size + buffer_prop->alignment - 1) &
   8640             (~(buffer_prop->alignment - 1));
   8641 
   8642         drv_ctx.extradata_info.size = buffer_prop->actualcount * final_extra_data_size;
   8643         drv_ctx.extradata_info.count = buffer_prop->actualcount;
   8644         drv_ctx.extradata_info.buffer_size = final_extra_data_size;
   8645         if (!secure_mode)
   8646             buf_size += final_extra_data_size;
   8647         buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   8648         DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%u) BufSize(%d)",
   8649                 buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size, buf_size);
   8650         if (extra_data_size)
   8651             DEBUG_PRINT_LOW("GetBufReq UPDATE: extradata: TotalSize(%d) BufferSize(%lu)",
   8652                 drv_ctx.extradata_info.size, drv_ctx.extradata_info.buffer_size);
   8653 
   8654         if (in_reconfig) // BufReq will be set to driver when port is disabled
   8655             buffer_prop->buffer_size = buf_size;
   8656         else if (buf_size != buffer_prop->buffer_size) {
   8657             buffer_prop->buffer_size = buf_size;
   8658             eRet = set_buffer_req(buffer_prop);
   8659         }
   8660     }
   8661     DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%u)",
   8662             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   8663     return eRet;
   8664 }
   8665 
   8666 OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
   8667 {
   8668     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8669     unsigned buf_size = 0;
   8670     struct v4l2_format fmt;
   8671     struct v4l2_requestbuffers bufreq;
   8672     int ret;
   8673     DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%u)",
   8674             buffer_prop->actualcount, (unsigned int)buffer_prop->buffer_size);
   8675     buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
   8676     if (buf_size != buffer_prop->buffer_size) {
   8677         DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%u) Required(%d)",
   8678                 (unsigned int)buffer_prop->buffer_size, buf_size);
   8679         eRet = OMX_ErrorBadParameter;
   8680     } else {
   8681         memset(&fmt, 0x0, sizeof(struct v4l2_format));
   8682         fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   8683         fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   8684 
   8685         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   8686             fmt.type =V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8687             fmt.fmt.pix_mp.pixelformat = output_capability;
   8688             fmt.fmt.pix_mp.plane_fmt[0].sizeimage = buf_size;
   8689         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   8690             fmt.type =V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8691             fmt.fmt.pix_mp.pixelformat = capture_capability;
   8692         } else {
   8693             eRet = OMX_ErrorBadParameter;
   8694         }
   8695 
   8696         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   8697         if (ret) {
   8698             /*TODO: How to handle this case */
   8699             DEBUG_PRINT_ERROR("Setting buffer requirements (format) failed %d", ret);
   8700             eRet = OMX_ErrorInsufficientResources;
   8701         }
   8702 
   8703         bufreq.memory = V4L2_MEMORY_USERPTR;
   8704         bufreq.count = buffer_prop->actualcount;
   8705         if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_INPUT) {
   8706             bufreq.type=V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8707         } else if (buffer_prop->buffer_type == VDEC_BUFFER_TYPE_OUTPUT) {
   8708             bufreq.type=V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8709         } else {
   8710             eRet = OMX_ErrorBadParameter;
   8711         }
   8712 
   8713         if (eRet==OMX_ErrorNone) {
   8714             ret = ioctl(drv_ctx.video_driver_fd,VIDIOC_REQBUFS, &bufreq);
   8715         }
   8716 
   8717         if (ret) {
   8718             DEBUG_PRINT_ERROR("Setting buffer requirements (reqbufs) failed %d", ret);
   8719             /*TODO: How to handle this case */
   8720             eRet = OMX_ErrorInsufficientResources;
   8721         } else if (bufreq.count < buffer_prop->actualcount) {
   8722             DEBUG_PRINT_ERROR("Driver refused to change the number of buffers"
   8723                     " on v4l2 port %d to %d (prefers %d)", bufreq.type,
   8724                     buffer_prop->actualcount, bufreq.count);
   8725             eRet = OMX_ErrorInsufficientResources;
   8726         } else {
   8727             if (!client_buffers.update_buffer_req()) {
   8728                 DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
   8729                 eRet = OMX_ErrorInsufficientResources;
   8730             }
   8731         }
   8732     }
   8733     return eRet;
   8734 }
   8735 
   8736 OMX_ERRORTYPE omx_vdec::update_picture_resolution()
   8737 {
   8738     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8739     return eRet;
   8740 }
   8741 
   8742 OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
   8743 {
   8744     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8745     struct v4l2_format fmt;
   8746     if (!portDefn) {
   8747         return OMX_ErrorBadParameter;
   8748     }
   8749     DEBUG_PRINT_LOW("omx_vdec::update_portdef");
   8750     portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
   8751     portDefn->nSize = sizeof(portDefn);
   8752     portDefn->eDomain    = OMX_PortDomainVideo;
   8753     if (drv_ctx.frame_rate.fps_denominator > 0)
   8754         portDefn->format.video.xFramerate = (drv_ctx.frame_rate.fps_numerator /
   8755             drv_ctx.frame_rate.fps_denominator) << 16; //Q16 format
   8756     else {
   8757         DEBUG_PRINT_ERROR("Error: Divide by zero");
   8758         return OMX_ErrorBadParameter;
   8759     }
   8760     memset(&fmt, 0x0, sizeof(struct v4l2_format));
   8761     if (0 == portDefn->nPortIndex) {
   8762         portDefn->eDir =  OMX_DirInput;
   8763         portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
   8764         portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
   8765         portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size;
   8766         portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
   8767         portDefn->format.video.eCompressionFormat = eCompressionFormat;
   8768         portDefn->bEnabled   = m_inp_bEnabled;
   8769         portDefn->bPopulated = m_inp_bPopulated;
   8770 
   8771         fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   8772         fmt.fmt.pix_mp.pixelformat = output_capability;
   8773     } else if (1 == portDefn->nPortIndex) {
   8774         unsigned int buf_size = 0;
   8775         if (!client_buffers.update_buffer_req()) {
   8776             DEBUG_PRINT_ERROR("client_buffers.update_buffer_req Failed");
   8777             return OMX_ErrorHardware;
   8778         }
   8779         if (!client_buffers.get_buffer_req(buf_size)) {
   8780             DEBUG_PRINT_ERROR("update buffer requirements");
   8781             return OMX_ErrorHardware;
   8782         }
   8783         portDefn->nBufferSize = buf_size;
   8784         portDefn->eDir =  OMX_DirOutput;
   8785         portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
   8786         portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
   8787         portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
   8788         portDefn->bEnabled   = m_out_bEnabled;
   8789         portDefn->bPopulated = m_out_bPopulated;
   8790         if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
   8791             DEBUG_PRINT_ERROR("Error in getting color format");
   8792             return OMX_ErrorHardware;
   8793         }
   8794         fmt.type = V4L2_BUF_TYPE_VIDEO_CAPTURE_MPLANE;
   8795         fmt.fmt.pix_mp.pixelformat = capture_capability;
   8796     } else {
   8797         portDefn->eDir = OMX_DirMax;
   8798         DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
   8799                 (int)portDefn->nPortIndex);
   8800         eRet = OMX_ErrorBadPortIndex;
   8801     }
   8802     if (is_down_scalar_enabled) {
   8803         int ret = 0;
   8804         ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_G_FMT, &fmt);
   8805         if (ret) {
   8806             DEBUG_PRINT_ERROR("update_portdef : Error in getting port resolution");
   8807             return OMX_ErrorHardware;
   8808         } else {
   8809             portDefn->format.video.nFrameWidth = fmt.fmt.pix_mp.width;
   8810             portDefn->format.video.nFrameHeight = fmt.fmt.pix_mp.height;
   8811             portDefn->format.video.nStride = fmt.fmt.pix_mp.plane_fmt[0].bytesperline;
   8812             portDefn->format.video.nSliceHeight = fmt.fmt.pix_mp.plane_fmt[0].reserved[0];
   8813         }
   8814     } else {
   8815     portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
   8816     portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
   8817     portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
   8818     portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
   8819     }
   8820 
   8821     if ((portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420Planar) ||
   8822        (portDefn->format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)) {
   8823            portDefn->format.video.nStride = ALIGN(drv_ctx.video_resolution.frame_width, 16);
   8824         portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.frame_height;
   8825     }
   8826     DEBUG_PRINT_HIGH("update_portdef(%u): Width = %u Height = %u Stride = %d "
   8827             "SliceHeight = %u eColorFormat = %d nBufSize %u nBufCnt %u",
   8828             (unsigned int)portDefn->nPortIndex,
   8829             (unsigned int)portDefn->format.video.nFrameWidth,
   8830             (unsigned int)portDefn->format.video.nFrameHeight,
   8831             (int)portDefn->format.video.nStride,
   8832             (unsigned int)portDefn->format.video.nSliceHeight,
   8833             (unsigned int)portDefn->format.video.eColorFormat,
   8834             (unsigned int)portDefn->nBufferSize,
   8835             (unsigned int)portDefn->nBufferCountActual);
   8836 
   8837     return eRet;
   8838 }
   8839 
   8840 OMX_ERRORTYPE omx_vdec::allocate_output_headers()
   8841 {
   8842     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   8843     OMX_BUFFERHEADERTYPE *bufHdr = NULL;
   8844     unsigned i= 0;
   8845 
   8846     if (!m_out_mem_ptr) {
   8847         DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
   8848         int nBufHdrSize        = 0;
   8849         int nPlatformEntrySize = 0;
   8850         int nPlatformListSize  = 0;
   8851         int nPMEMInfoSize = 0;
   8852         OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
   8853         OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
   8854         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
   8855 
   8856         DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
   8857                 drv_ctx.op_buf.actualcount);
   8858         nBufHdrSize        = drv_ctx.op_buf.actualcount *
   8859             sizeof(OMX_BUFFERHEADERTYPE);
   8860 
   8861         nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
   8862             sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
   8863         nPlatformListSize  = drv_ctx.op_buf.actualcount *
   8864             sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
   8865         nPlatformEntrySize = drv_ctx.op_buf.actualcount *
   8866             sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
   8867 
   8868         DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %u PMEM %d PL %d",nBufHdrSize,
   8869                 (unsigned int)sizeof(OMX_BUFFERHEADERTYPE),
   8870                 nPMEMInfoSize,
   8871                 nPlatformListSize);
   8872         DEBUG_PRINT_LOW("PE %d bmSize % " PRId64 , nPlatformEntrySize,
   8873                 m_out_bm_count);
   8874         m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
   8875         // Alloc mem for platform specific info
   8876         char *pPtr=NULL;
   8877         pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
   8878                 nPMEMInfoSize,1);
   8879         drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
   8880                        calloc (sizeof(struct vdec_bufferpayload),
   8881                                drv_ctx.op_buf.actualcount);
   8882         drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
   8883                      calloc (sizeof (struct vdec_output_frameinfo),
   8884                              drv_ctx.op_buf.actualcount);
   8885         if (!drv_ctx.ptr_outputbuffer || !drv_ctx.ptr_respbuffer) {
   8886             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.ptr_outputbuffer or drv_ctx.ptr_respbuffer");
   8887             return OMX_ErrorInsufficientResources;
   8888         }
   8889 
   8890 #ifdef USE_ION
   8891         drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
   8892                       calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
   8893         if (!drv_ctx.op_buf_ion_info) {
   8894             DEBUG_PRINT_ERROR("Failed to alloc drv_ctx.op_buf_ion_info");
   8895             return OMX_ErrorInsufficientResources;
   8896         }
   8897 #endif
   8898         if (dynamic_buf_mode) {
   8899             out_dynamic_list = (struct dynamic_buf_list *) \
   8900                 calloc (sizeof(struct dynamic_buf_list), drv_ctx.op_buf.actualcount);
   8901         }
   8902 
   8903         if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
   8904                 && drv_ctx.ptr_respbuffer) {
   8905             bufHdr          =  m_out_mem_ptr;
   8906             m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
   8907             m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
   8908                 (((char *) m_platform_list)  + nPlatformListSize);
   8909             m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
   8910                 (((char *) m_platform_entry) + nPlatformEntrySize);
   8911             pPlatformList   = m_platform_list;
   8912             pPlatformEntry  = m_platform_entry;
   8913             pPMEMInfo       = m_pmem_info;
   8914 
   8915             DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
   8916 
   8917             // Settting the entire storage nicely
   8918             DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
   8919                     m_out_mem_ptr,pPlatformEntry);
   8920             DEBUG_PRINT_LOW(" Pmem Info = %p",pPMEMInfo);
   8921             for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
   8922                 bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
   8923                 bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
   8924                 // Set the values when we determine the right HxW param
   8925                 bufHdr->nAllocLen          = 0;
   8926                 bufHdr->nFilledLen         = 0;
   8927                 bufHdr->pAppPrivate        = NULL;
   8928                 bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
   8929                 pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   8930                 pPlatformEntry->entry      = pPMEMInfo;
   8931                 // Initialize the Platform List
   8932                 pPlatformList->nEntries    = 1;
   8933                 pPlatformList->entryList   = pPlatformEntry;
   8934                 // Keep pBuffer NULL till vdec is opened
   8935                 bufHdr->pBuffer            = NULL;
   8936                 pPMEMInfo->offset          =  0;
   8937                 pPMEMInfo->pmem_fd = 0;
   8938                 bufHdr->pPlatformPrivate = pPlatformList;
   8939                 drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
   8940 #ifdef USE_ION
   8941                 drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
   8942 #endif
   8943                 /*Create a mapping between buffers*/
   8944                 bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
   8945                 drv_ctx.ptr_respbuffer[i].client_data = (void *) \
   8946                                     &drv_ctx.ptr_outputbuffer[i];
   8947                 // Move the buffer and buffer header pointers
   8948                 bufHdr++;
   8949                 pPMEMInfo++;
   8950                 pPlatformEntry++;
   8951                 pPlatformList++;
   8952             }
   8953         } else {
   8954             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%p][0x%p]",\
   8955                     m_out_mem_ptr, pPtr);
   8956             if (m_out_mem_ptr) {
   8957                 free(m_out_mem_ptr);
   8958                 m_out_mem_ptr = NULL;
   8959             }
   8960             if (pPtr) {
   8961                 free(pPtr);
   8962                 pPtr = NULL;
   8963             }
   8964             if (drv_ctx.ptr_outputbuffer) {
   8965                 free(drv_ctx.ptr_outputbuffer);
   8966                 drv_ctx.ptr_outputbuffer = NULL;
   8967             }
   8968             if (drv_ctx.ptr_respbuffer) {
   8969                 free(drv_ctx.ptr_respbuffer);
   8970                 drv_ctx.ptr_respbuffer = NULL;
   8971             }
   8972 #ifdef USE_ION
   8973             if (drv_ctx.op_buf_ion_info) {
   8974                 DEBUG_PRINT_LOW("Free o/p ion context");
   8975                 free(drv_ctx.op_buf_ion_info);
   8976                 drv_ctx.op_buf_ion_info = NULL;
   8977             }
   8978 #endif
   8979             eRet =  OMX_ErrorInsufficientResources;
   8980         }
   8981     } else {
   8982         eRet =  OMX_ErrorInsufficientResources;
   8983     }
   8984     return eRet;
   8985 }
   8986 
   8987 void omx_vdec::complete_pending_buffer_done_cbs()
   8988 {
   8989     unsigned long p1, p2, ident;
   8990     omx_cmd_queue tmp_q, pending_bd_q;
   8991     pthread_mutex_lock(&m_lock);
   8992     // pop all pending GENERATE FDB from ftb queue
   8993     while (m_ftb_q.m_size) {
   8994         m_ftb_q.pop_entry(&p1,&p2,&ident);
   8995         if (ident == OMX_COMPONENT_GENERATE_FBD) {
   8996             pending_bd_q.insert_entry(p1,p2,ident);
   8997         } else {
   8998             tmp_q.insert_entry(p1,p2,ident);
   8999         }
   9000     }
   9001     //return all non GENERATE FDB to ftb queue
   9002     while (tmp_q.m_size) {
   9003         tmp_q.pop_entry(&p1,&p2,&ident);
   9004         m_ftb_q.insert_entry(p1,p2,ident);
   9005     }
   9006     // pop all pending GENERATE EDB from etb queue
   9007     while (m_etb_q.m_size) {
   9008         m_etb_q.pop_entry(&p1,&p2,&ident);
   9009         if (ident == OMX_COMPONENT_GENERATE_EBD) {
   9010             pending_bd_q.insert_entry(p1,p2,ident);
   9011         } else {
   9012             tmp_q.insert_entry(p1,p2,ident);
   9013         }
   9014     }
   9015     //return all non GENERATE FDB to etb queue
   9016     while (tmp_q.m_size) {
   9017         tmp_q.pop_entry(&p1,&p2,&ident);
   9018         m_etb_q.insert_entry(p1,p2,ident);
   9019     }
   9020     pthread_mutex_unlock(&m_lock);
   9021     // process all pending buffer dones
   9022     while (pending_bd_q.m_size) {
   9023         pending_bd_q.pop_entry(&p1,&p2,&ident);
   9024         switch (ident) {
   9025             case OMX_COMPONENT_GENERATE_EBD:
   9026                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
   9027                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
   9028                     omx_report_error ();
   9029                 }
   9030                 break;
   9031 
   9032             case OMX_COMPONENT_GENERATE_FBD:
   9033                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
   9034                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
   9035                     omx_report_error ();
   9036                 }
   9037                 break;
   9038         }
   9039     }
   9040 }
   9041 
   9042 void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
   9043 {
   9044     OMX_U32 new_frame_interval = 0;
   9045     if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
   9046             && llabs(act_timestamp - prev_ts) > 2000) {
   9047         new_frame_interval = client_set_fps ? frm_int :
   9048             llabs(act_timestamp - prev_ts);
   9049         if (new_frame_interval != frm_int || frm_int == 0) {
   9050             frm_int = new_frame_interval;
   9051             if (frm_int) {
   9052                 drv_ctx.frame_rate.fps_numerator = 1e6;
   9053                 drv_ctx.frame_rate.fps_denominator = frm_int;
   9054                 DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
   9055                         (unsigned int)frm_int, drv_ctx.frame_rate.fps_numerator /
   9056                         (float)drv_ctx.frame_rate.fps_denominator);
   9057                 //m_perf_control.request_cores(frm_int);
   9058                 /* We need to report the difference between this FBD and the previous FBD
   9059                  * back to the driver for clock scaling purposes. */
   9060                 struct v4l2_outputparm oparm;
   9061                 /*XXX: we're providing timing info as seconds per frame rather than frames
   9062                  * per second.*/
   9063                 oparm.timeperframe.numerator = drv_ctx.frame_rate.fps_denominator;
   9064                 oparm.timeperframe.denominator = drv_ctx.frame_rate.fps_numerator;
   9065 
   9066                 struct v4l2_streamparm sparm;
   9067                 sparm.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   9068                 sparm.parm.output = oparm;
   9069                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_PARM, &sparm)) {
   9070                     DEBUG_PRINT_ERROR("Unable to convey fps info to driver, \
   9071                             performance might be affected");
   9072                 }
   9073 
   9074             }
   9075         }
   9076     }
   9077     prev_ts = act_timestamp;
   9078 }
   9079 
   9080 void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
   9081 {
   9082     if (rst_prev_ts && VALID_TS(act_timestamp)) {
   9083         prev_ts = act_timestamp;
   9084         rst_prev_ts = false;
   9085     } else if (VALID_TS(prev_ts)) {
   9086         bool codec_cond = (drv_ctx.timestamp_adjust)?
   9087             (!VALID_TS(act_timestamp) || act_timestamp < prev_ts || llabs(act_timestamp - prev_ts) <= 2000) :
   9088             (!VALID_TS(act_timestamp) || act_timestamp <= prev_ts);
   9089         if (frm_int > 0 && codec_cond) {
   9090             DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
   9091             act_timestamp = prev_ts + frm_int;
   9092             DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
   9093             prev_ts = act_timestamp;
   9094         } else {
   9095             if (drv_ctx.picture_order == VDEC_ORDER_DISPLAY && act_timestamp < prev_ts) {
   9096                 // ensure that timestamps can never step backwards when in display order
   9097                 act_timestamp = prev_ts;
   9098             }
   9099             set_frame_rate(act_timestamp);
   9100         }
   9101     } else if (frm_int > 0)          // In this case the frame rate was set along
   9102     {                               // with the port definition, start ts with 0
   9103         act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
   9104         rst_prev_ts = true;
   9105     }
   9106 }
   9107 
   9108 void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   9109 {
   9110     OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL;
   9111     OMX_U32 num_conceal_MB = 0;
   9112     OMX_TICKS time_stamp = 0;
   9113     OMX_U32 frame_rate = 0;
   9114     unsigned long consumed_len = 0;
   9115     OMX_U32 num_MB_in_frame;
   9116     OMX_U32 recovery_sei_flags = 1;
   9117     int enable = 0;
   9118 
   9119     //TODO: disable extradata
   9120     return;
   9121 
   9122     int buf_index = p_buf_hdr - m_out_mem_ptr;
   9123     if (buf_index >= drv_ctx.extradata_info.count) {
   9124         DEBUG_PRINT_ERROR("handle_extradata: invalid index(%d) max(%d)",
   9125                 buf_index, drv_ctx.extradata_info.count);
   9126         return;
   9127     }
   9128     struct msm_vidc_panscan_window_payload *panscan_payload = NULL;
   9129     OMX_U8 *pBuffer = (OMX_U8 *)(drv_ctx.ptr_outputbuffer[buf_index].bufferaddr) +
   9130         p_buf_hdr->nOffset;
   9131 
   9132     if (!drv_ctx.extradata_info.uaddr) {
   9133         DEBUG_PRINT_HIGH("NULL drv_ctx.extradata_info.uaddr");
   9134         return;
   9135     }
   9136     if (!secure_mode && (drv_ctx.extradata_info.buffer_size > (p_buf_hdr->nAllocLen - p_buf_hdr->nFilledLen)) ) {
   9137         DEBUG_PRINT_ERROR("Error: Insufficient size allocated for extra-data");
   9138         p_extra = NULL;
   9139         return;
   9140     }
   9141     if (!secure_mode)
   9142         p_extra = (OMX_OTHER_EXTRADATATYPE *)
   9143             ((unsigned long)(pBuffer + p_buf_hdr->nOffset + p_buf_hdr->nFilledLen + 3)&(~3));
   9144     else
   9145         p_extra = m_other_extradata;
   9146     char *p_extradata = drv_ctx.extradata_info.uaddr + buf_index * drv_ctx.extradata_info.buffer_size;
   9147 
   9148     if (!secure_mode && ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))) {
   9149         p_extra = NULL;
   9150         DEBUG_PRINT_ERROR("Error: out of bound memory access by p_extra");
   9151         return;
   9152     }
   9153     OMX_OTHER_EXTRADATATYPE *data = (struct OMX_OTHER_EXTRADATATYPE *)p_extradata;
   9154     if (data && p_extra) {
   9155         while ((consumed_len < drv_ctx.extradata_info.buffer_size)
   9156                 && (data->eType != (OMX_EXTRADATATYPE)MSM_VIDC_EXTRADATA_NONE)) {
   9157             if ((consumed_len + data->nSize) > (unsigned)drv_ctx.extradata_info.buffer_size) {
   9158                 DEBUG_PRINT_LOW("Invalid extra data size");
   9159                 break;
   9160             }
   9161             DEBUG_PRINT_LOW("handle_extradata: eType = %d", data->eType);
   9162             switch ((unsigned long)data->eType) {
   9163                 case MSM_VIDC_EXTRADATA_INTERLACE_VIDEO:
   9164                     struct msm_vidc_interlace_payload *payload;
   9165                     payload = (struct msm_vidc_interlace_payload *)(void *)data->data;
   9166                     if (payload) {
   9167                         enable = 1;
   9168                         switch (payload->format) {
   9169                             case MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE:
   9170                                 drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   9171                                 enable = 0;
   9172                                 break;
   9173                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST:
   9174                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   9175                                 break;
   9176                             case MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST:
   9177                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameBottomFieldFirst;
   9178                                 break;
   9179                             default:
   9180                                 DEBUG_PRINT_LOW("default case - set interlace to topfield");
   9181                                 drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   9182                         }
   9183                     }
   9184 
   9185                     if (m_enable_android_native_buffers) {
   9186                         DEBUG_PRINT_LOW("setMetaData INTERLACED format:%d enable:%d mbaff:%d",
   9187                                          payload->format, enable,
   9188                                         (p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF)?true:false);
   9189                         setMetaData((private_handle_t *)native_buffer[buf_index].privatehandle,
   9190                                PP_PARAM_INTERLACED, (void*)&enable);
   9191                     }
   9192                     if (client_extradata & OMX_INTERLACE_EXTRADATA) {
   9193                         append_interlace_extradata(p_extra, payload->format,
   9194                                       p_buf_hdr->nFlags & QOMX_VIDEO_BUFFERFLAG_MBAFF);
   9195                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9196                     }
   9197                     break;
   9198                 case MSM_VIDC_EXTRADATA_FRAME_RATE:
   9199                     struct msm_vidc_framerate_payload *frame_rate_payload;
   9200                     frame_rate_payload = (struct msm_vidc_framerate_payload *)(void *)data->data;
   9201                     frame_rate = frame_rate_payload->frame_rate;
   9202                     break;
   9203                 case MSM_VIDC_EXTRADATA_TIMESTAMP:
   9204                     struct msm_vidc_ts_payload *time_stamp_payload;
   9205                     time_stamp_payload = (struct msm_vidc_ts_payload *)(void *)data->data;
   9206                     time_stamp = time_stamp_payload->timestamp_lo;
   9207                     time_stamp |= ((unsigned long long)time_stamp_payload->timestamp_hi << 32);
   9208                     p_buf_hdr->nTimeStamp = time_stamp;
   9209                     break;
   9210                 case MSM_VIDC_EXTRADATA_NUM_CONCEALED_MB:
   9211                     struct msm_vidc_concealmb_payload *conceal_mb_payload;
   9212                     conceal_mb_payload = (struct msm_vidc_concealmb_payload *)(void *)data->data;
   9213                     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   9214                             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   9215                     num_conceal_MB = ((num_MB_in_frame > 0)?(conceal_mb_payload->num_mbs * 100 / num_MB_in_frame) : 0);
   9216                     break;
   9217                 case MSM_VIDC_EXTRADATA_INDEX:
   9218                     int *etype;
   9219                     etype  = (int *)(void *)data->data;
   9220                     if (etype && *etype == MSM_VIDC_EXTRADATA_ASPECT_RATIO) {
   9221                         struct msm_vidc_aspect_ratio_payload *aspect_ratio_payload;
   9222                         aspect_ratio_payload = (struct msm_vidc_aspect_ratio_payload *)(++etype);
   9223                         if (aspect_ratio_payload) {
   9224                             ((struct vdec_output_frameinfo *)
   9225                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_width = aspect_ratio_payload->aspect_width;
   9226                             ((struct vdec_output_frameinfo *)
   9227                              p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info.par_height = aspect_ratio_payload->aspect_height;
   9228                         }
   9229                     }
   9230                     break;
   9231                 case MSM_VIDC_EXTRADATA_RECOVERY_POINT_SEI:
   9232                     struct msm_vidc_recoverysei_payload *recovery_sei_payload;
   9233                     recovery_sei_payload = (struct msm_vidc_recoverysei_payload *)(void *)data->data;
   9234                     recovery_sei_flags = recovery_sei_payload->flags;
   9235                     if (recovery_sei_flags != MSM_VIDC_FRAME_RECONSTRUCTION_CORRECT) {
   9236                         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_DATACORRUPT;
   9237                         DEBUG_PRINT_HIGH("***************************************************");
   9238                         DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   9239                         DEBUG_PRINT_HIGH("***************************************************");
   9240                     }
   9241                     break;
   9242                case MSM_VIDC_EXTRADATA_PANSCAN_WINDOW:
   9243                     panscan_payload = (struct msm_vidc_panscan_window_payload *)(void *)data->data;
   9244                     if (panscan_payload->num_panscan_windows > MAX_PAN_SCAN_WINDOWS) {
   9245                         DEBUG_PRINT_ERROR("Panscan windows are more than supported\n");
   9246                         DEBUG_PRINT_ERROR("Max supported = %d FW returned = %d\n",
   9247                             MAX_PAN_SCAN_WINDOWS, panscan_payload->num_panscan_windows);
   9248                         return;
   9249                     }
   9250                     break;
   9251                 case MSM_VIDC_EXTRADATA_MPEG2_SEQDISP:
   9252                     struct msm_vidc_mpeg2_seqdisp_payload *seqdisp_payload;
   9253                     seqdisp_payload = (struct msm_vidc_mpeg2_seqdisp_payload *)(void *)data->data;
   9254                     if (seqdisp_payload) {
   9255                         m_disp_hor_size = seqdisp_payload->disp_width;
   9256                         m_disp_vert_size = seqdisp_payload->disp_height;
   9257                         if (client_extradata & OMX_MPEG2SEQDISP_EXTRADATA) {
   9258                             append_mpeg2_seqdisplay_extradata(p_extra, seqdisp_payload);
   9259                             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9260                         }
   9261                     }
   9262                     break;
   9263                 case MSM_VIDC_EXTRADATA_S3D_FRAME_PACKING:
   9264                     struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload;
   9265                     s3d_frame_packing_payload = (struct msm_vidc_s3d_frame_packing_payload *)(void *)data->data;
   9266                     if (client_extradata & OMX_FRAMEPACK_EXTRADATA) {
   9267                         append_framepack_extradata(p_extra, s3d_frame_packing_payload);
   9268                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9269                     }
   9270                     break;
   9271                 case MSM_VIDC_EXTRADATA_FRAME_QP:
   9272                     struct msm_vidc_frame_qp_payload *qp_payload;
   9273                     qp_payload = (struct msm_vidc_frame_qp_payload*)(void *)data->data;
   9274                     if (client_extradata & OMX_QP_EXTRADATA) {
   9275                         append_qp_extradata(p_extra, qp_payload);
   9276                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9277                     }
   9278                     break;
   9279                 case MSM_VIDC_EXTRADATA_FRAME_BITS_INFO:
   9280                     struct msm_vidc_frame_bits_info_payload *bits_info_payload;
   9281                     bits_info_payload = (struct msm_vidc_frame_bits_info_payload*)(void *)data->data;
   9282                     if (client_extradata & OMX_BITSINFO_EXTRADATA) {
   9283                         append_bitsinfo_extradata(p_extra, bits_info_payload);
   9284                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9285                     }
   9286                     break;
   9287                 case MSM_VIDC_EXTRADATA_STREAM_USERDATA:
   9288                     if (client_extradata & OMX_EXTNUSER_EXTRADATA) {
   9289                         append_user_extradata(p_extra, data);
   9290                         p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9291                     }
   9292                     break;
   9293                 default:
   9294                     DEBUG_PRINT_LOW("Unrecognized extradata");
   9295                     goto unrecognized_extradata;
   9296             }
   9297             consumed_len += data->nSize;
   9298             data = (OMX_OTHER_EXTRADATATYPE *)((char *)data + data->nSize);
   9299         }
   9300         if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
   9301             p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   9302             append_frame_info_extradata(p_extra,
   9303                     num_conceal_MB, ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type, frame_rate,
   9304                     time_stamp, panscan_payload,&((struct vdec_output_frameinfo *)
   9305                         p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
   9306             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9307         }
   9308         if (client_extradata & OMX_FRAMEDIMENSION_EXTRADATA) {
   9309             append_frame_dimension_extradata(p_extra);
   9310             p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
   9311         }
   9312     }
   9313 unrecognized_extradata:
   9314     if (client_extradata && p_extra) {
   9315         p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
   9316         append_terminator_extradata(p_extra);
   9317     }
   9318     if (secure_mode && p_extradata && m_other_extradata) {
   9319         struct vdec_output_frameinfo  *ptr_extradatabuff = NULL;
   9320         memcpy(p_extradata, m_other_extradata, drv_ctx.extradata_info.buffer_size);
   9321         ptr_extradatabuff = (struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate;
   9322         ptr_extradatabuff->metadata_info.metabufaddr = (void *)p_extradata;
   9323         ptr_extradatabuff->metadata_info.size = drv_ctx.extradata_info.buffer_size;
   9324     }
   9325     return;
   9326 }
   9327 
   9328 OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata,
   9329         bool is_internal, bool enable)
   9330 {
   9331     OMX_ERRORTYPE ret = OMX_ErrorNone;
   9332     struct v4l2_control control;
   9333     if (m_state != OMX_StateLoaded) {
   9334         DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
   9335         return OMX_ErrorIncorrectStateOperation;
   9336     }
   9337     //TODO: disable extradata
   9338     return ret;
   9339 
   9340     DEBUG_PRINT_HIGH("NOTE: enable_extradata: actual[%u] requested[%u] enable[%d], is_internal: %d",
   9341             (unsigned int)client_extradata, (unsigned int)requested_extradata, enable, is_internal);
   9342 
   9343     if (!is_internal) {
   9344         if (enable)
   9345             client_extradata |= requested_extradata;
   9346         else
   9347             client_extradata = client_extradata & ~requested_extradata;
   9348     }
   9349 
   9350     if (enable) {
   9351         if (requested_extradata & OMX_INTERLACE_EXTRADATA) {
   9352             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9353             control.value = V4L2_MPEG_VIDC_EXTRADATA_INTERLACE_VIDEO;
   9354             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9355                 DEBUG_PRINT_HIGH("Failed to set interlaced extradata."
   9356                         " Quality of interlaced clips might be impacted.");
   9357             }
   9358         }
   9359         if (requested_extradata & OMX_FRAMEINFO_EXTRADATA) {
   9360             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9361             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_RATE;
   9362             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9363                 DEBUG_PRINT_HIGH("Failed to set framerate extradata");
   9364             }
   9365             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9366             control.value = V4L2_MPEG_VIDC_EXTRADATA_NUM_CONCEALED_MB;
   9367             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9368                 DEBUG_PRINT_HIGH("Failed to set concealed MB extradata");
   9369             }
   9370             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9371             control.value = V4L2_MPEG_VIDC_EXTRADATA_RECOVERY_POINT_SEI;
   9372             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9373                 DEBUG_PRINT_HIGH("Failed to set recovery point SEI extradata");
   9374             }
   9375             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9376             control.value = V4L2_MPEG_VIDC_EXTRADATA_PANSCAN_WINDOW;
   9377             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9378                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   9379             }
   9380             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9381             control.value = V4L2_MPEG_VIDC_EXTRADATA_ASPECT_RATIO;
   9382             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9383                 DEBUG_PRINT_HIGH("Failed to set panscan extradata");
   9384             }
   9385             }
   9386         if (requested_extradata & OMX_TIMEINFO_EXTRADATA) {
   9387             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9388             control.value = V4L2_MPEG_VIDC_EXTRADATA_TIMESTAMP;
   9389             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9390                 DEBUG_PRINT_HIGH("Failed to set timeinfo extradata");
   9391             }
   9392         }
   9393         if (requested_extradata & OMX_FRAMEPACK_EXTRADATA) {
   9394             if (output_capability == V4L2_PIX_FMT_H264) {
   9395                 DEBUG_PRINT_HIGH("enable OMX_FRAMEPACK_EXTRADATA");
   9396                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9397                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_S3D_FRAME_PACKING;
   9398                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9399                     DEBUG_PRINT_HIGH("Failed to set S3D_FRAME_PACKING extradata");
   9400                 }
   9401             } else {
   9402                 DEBUG_PRINT_HIGH("OMX_FRAMEPACK_EXTRADATA supported for H264 only");
   9403             }
   9404         }
   9405         if (requested_extradata & OMX_QP_EXTRADATA) {
   9406             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9407             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_QP;
   9408             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9409                 DEBUG_PRINT_HIGH("Failed to set QP extradata");
   9410             }
   9411         }
   9412         if (requested_extradata & OMX_BITSINFO_EXTRADATA) {
   9413             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9414             control.value = V4L2_MPEG_VIDC_EXTRADATA_FRAME_BITS_INFO;
   9415             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9416                 DEBUG_PRINT_HIGH("Failed to set frame bits info extradata");
   9417             }
   9418         }
   9419         if (requested_extradata & OMX_EXTNUSER_EXTRADATA) {
   9420             control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9421             control.value = V4L2_MPEG_VIDC_EXTRADATA_STREAM_USERDATA;
   9422             if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9423                 DEBUG_PRINT_HIGH("Failed to set stream userdata extradata");
   9424             }
   9425         }
   9426         if (requested_extradata & OMX_MPEG2SEQDISP_EXTRADATA) {
   9427             if (output_capability == V4L2_PIX_FMT_MPEG2) {
   9428                 DEBUG_PRINT_HIGH("Enable seq display extradata");
   9429                 control.id = V4L2_CID_MPEG_VIDC_VIDEO_EXTRADATA;
   9430                 control.value =  V4L2_MPEG_VIDC_EXTRADATA_MPEG2_SEQDISP;
   9431                 if (ioctl(drv_ctx.video_driver_fd, VIDIOC_S_CTRL, &control)) {
   9432                     DEBUG_PRINT_HIGH("Failed to set seqdisp extradata");
   9433                 }
   9434             } else {
   9435                 DEBUG_PRINT_HIGH("Seq display extradata is supported for MPEG2 only");
   9436             }
   9437         }
   9438     }
   9439     ret = get_buffer_req(&drv_ctx.op_buf);
   9440     return ret;
   9441 }
   9442 
   9443 OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   9444 {
   9445     OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
   9446     OMX_U8 *data_ptr = extra->data, data = 0;
   9447     while (byte_count < extra->nDataSize) {
   9448         data = *data_ptr;
   9449         while (data) {
   9450             num_MB += (data&0x01);
   9451             data >>= 1;
   9452         }
   9453         data_ptr++;
   9454         byte_count++;
   9455     }
   9456     num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
   9457             (drv_ctx.video_resolution.frame_height + 15)) >> 8;
   9458     return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
   9459 }
   9460 
   9461 void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   9462 {
   9463     if (!m_debug_extradata || !extra)
   9464         return;
   9465 
   9466 
   9467     DEBUG_PRINT_HIGH(
   9468             "============== Extra Data ==============\n"
   9469             "           Size: %u\n"
   9470             "        Version: %u\n"
   9471             "      PortIndex: %u\n"
   9472             "           Type: %x\n"
   9473             "       DataSize: %u",
   9474             (unsigned int)extra->nSize, (unsigned int)extra->nVersion.nVersion,
   9475             (unsigned int)extra->nPortIndex, extra->eType, (unsigned int)extra->nDataSize);
   9476 
   9477     if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat) {
   9478         OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   9479         DEBUG_PRINT_HIGH(
   9480                 "------ Interlace Format ------\n"
   9481                 "                Size: %u\n"
   9482                 "             Version: %u\n"
   9483                 "           PortIndex: %u\n"
   9484                 " Is Interlace Format: %d\n"
   9485                 "   Interlace Formats: %u\n"
   9486                 "=========== End of Interlace ===========",
   9487                 (unsigned int)intfmt->nSize, (unsigned int)intfmt->nVersion.nVersion, (unsigned int)intfmt->nPortIndex,
   9488                 intfmt->bInterlaceFormat, (unsigned int)intfmt->nInterlaceFormats);
   9489     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo) {
   9490         OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   9491 
   9492         DEBUG_PRINT_HIGH(
   9493                 "-------- Frame Format --------\n"
   9494                 "             Picture Type: %d\n"
   9495                 "           Interlace Type: %d\n"
   9496                 " Pan Scan Total Frame Num: %u\n"
   9497                 "   Concealed Macro Blocks: %u\n"
   9498                 "               frame rate: %u\n"
   9499                 "               Time Stamp: %llu\n"
   9500                 "           Aspect Ratio X: %u\n"
   9501                 "           Aspect Ratio Y: %u",
   9502                 fminfo->ePicType,
   9503                 fminfo->interlaceType,
   9504                 (unsigned int)fminfo->panScan.numWindows,
   9505                 (unsigned int)fminfo->nConcealedMacroblocks,
   9506                 (unsigned int)fminfo->nFrameRate,
   9507                 fminfo->nTimeStamp,
   9508                 (unsigned int)fminfo->aspectRatio.aspectRatioX,
   9509                 (unsigned int)fminfo->aspectRatio.aspectRatioY);
   9510 
   9511         for (OMX_U32 i = 0; i < fminfo->panScan.numWindows; i++) {
   9512             DEBUG_PRINT_HIGH(
   9513                     "------------------------------"
   9514                     "     Pan Scan Frame Num: %u\n"
   9515                     "            Rectangle x: %d\n"
   9516                     "            Rectangle y: %d\n"
   9517                     "           Rectangle dx: %d\n"
   9518                     "           Rectangle dy: %d",
   9519                     (unsigned int)i, (unsigned int)fminfo->panScan.window[i].x, (unsigned int)fminfo->panScan.window[i].y,
   9520                     (unsigned int)fminfo->panScan.window[i].dx, (unsigned int)fminfo->panScan.window[i].dy);
   9521         }
   9522 
   9523         DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
   9524     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement) {
   9525         OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   9526         DEBUG_PRINT_HIGH(
   9527                 "------------------ Framepack Format ----------\n"
   9528                 "                           id: %u \n"
   9529                 "                  cancel_flag: %u \n"
   9530                 "                         type: %u \n"
   9531                 " quincunx_sampling_flagFormat: %u \n"
   9532                 "  content_interpretation_type: %u \n"
   9533                 "        spatial_flipping_flag: %u \n"
   9534                 "          frame0_flipped_flag: %u \n"
   9535                 "             field_views_flag: %u \n"
   9536                 " current_frame_is_frame0_flag: %u \n"
   9537                 "   frame0_self_contained_flag: %u \n"
   9538                 "   frame1_self_contained_flag: %u \n"
   9539                 "       frame0_grid_position_x: %u \n"
   9540                 "       frame0_grid_position_y: %u \n"
   9541                 "       frame1_grid_position_x: %u \n"
   9542                 "       frame1_grid_position_y: %u \n"
   9543                 "                reserved_byte: %u \n"
   9544                 "            repetition_period: %u \n"
   9545                 "               extension_flag: %u \n"
   9546                 "================== End of Framepack ===========",
   9547                 (unsigned int)framepack->id,
   9548                 (unsigned int)framepack->cancel_flag,
   9549                 (unsigned int)framepack->type,
   9550                 (unsigned int)framepack->quincunx_sampling_flag,
   9551                 (unsigned int)framepack->content_interpretation_type,
   9552                 (unsigned int)framepack->spatial_flipping_flag,
   9553                 (unsigned int)framepack->frame0_flipped_flag,
   9554                 (unsigned int)framepack->field_views_flag,
   9555                 (unsigned int)framepack->current_frame_is_frame0_flag,
   9556                 (unsigned int)framepack->frame0_self_contained_flag,
   9557                 (unsigned int)framepack->frame1_self_contained_flag,
   9558                 (unsigned int)framepack->frame0_grid_position_x,
   9559                 (unsigned int)framepack->frame0_grid_position_y,
   9560                 (unsigned int)framepack->frame1_grid_position_x,
   9561                 (unsigned int)framepack->frame1_grid_position_y,
   9562                 (unsigned int)framepack->reserved_byte,
   9563                 (unsigned int)framepack->repetition_period,
   9564                 (unsigned int)framepack->extension_flag);
   9565     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataQP) {
   9566         OMX_QCOM_EXTRADATA_QP * qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   9567         DEBUG_PRINT_HIGH(
   9568                 "---- QP (Frame quantization parameter) ----\n"
   9569                 "    Frame QP: %u \n"
   9570                 "================ End of QP ================\n",
   9571                 (unsigned int)qp->nQP);
   9572     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo) {
   9573         OMX_QCOM_EXTRADATA_BITS_INFO * bits = (OMX_QCOM_EXTRADATA_BITS_INFO *)(void *)extra->data;
   9574         DEBUG_PRINT_HIGH(
   9575                 "--------- Input bits information --------\n"
   9576                 "    Header bits: %u \n"
   9577                 "     Frame bits: %u \n"
   9578                 "===== End of Input bits information =====\n",
   9579                 (unsigned int)bits->header_bits, (unsigned int)bits->frame_bits);
   9580     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData) {
   9581         OMX_QCOM_EXTRADATA_USERDATA *userdata = (OMX_QCOM_EXTRADATA_USERDATA *)(void *)extra->data;
   9582         OMX_U8 *data_ptr = (OMX_U8 *)userdata->data;
   9583         OMX_U32 userdata_size = extra->nDataSize - sizeof(userdata->type);
   9584         OMX_U32 i = 0;
   9585         DEBUG_PRINT_HIGH(
   9586                 "--------------  Userdata  -------------\n"
   9587                 "    Stream userdata type: %u\n"
   9588                 "          userdata size: %u\n"
   9589                 "    STREAM_USERDATA:",
   9590                 (unsigned int)userdata->type, (unsigned int)userdata_size);
   9591                 for (i = 0; i < userdata_size; i+=4) {
   9592                     DEBUG_PRINT_HIGH("        %x %x %x %x",
   9593                         data_ptr[i], data_ptr[i+1],
   9594                         data_ptr[i+2], data_ptr[i+3]);
   9595                 }
   9596         DEBUG_PRINT_HIGH(
   9597                 "=========== End of Userdata ===========");
   9598     } else if (extra->eType == (OMX_EXTRADATATYPE)OMX_ExtraDataMpeg2SeqDisplay) {
   9599         OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *seq_display = (OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY*)(void*)extra->data;
   9600         DEBUG_PRINT_HIGH(
   9601                 "------Mpeg2SeqDisplay ------\n"
   9602                 "     Frame Width: %d\n"
   9603                 "    Frame Height: %d\n"
   9604                 "=========== End of Mpeg2SeqDisplay ===========",
   9605                 seq_display->disp_width, seq_display->disp_height);
   9606     } else if (extra->eType == OMX_ExtraDataNone) {
   9607         DEBUG_PRINT_HIGH("========== End of Terminator ===========");
   9608     } else {
   9609         DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
   9610     }
   9611 }
   9612 
   9613 void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9614         OMX_U32 interlaced_format_type, bool is_mbaff)
   9615 {
   9616     OMX_STREAMINTERLACEFORMAT *interlace_format;
   9617 
   9618     if (!(client_extradata & OMX_INTERLACE_EXTRADATA)) {
   9619         return;
   9620     }
   9621     extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
   9622     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9623     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9624     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
   9625     extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   9626     interlace_format = (OMX_STREAMINTERLACEFORMAT *)(void *)extra->data;
   9627     interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
   9628     interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
   9629     interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9630 
   9631     if ((interlaced_format_type == MSM_VIDC_INTERLACE_FRAME_PROGRESSIVE) && !is_mbaff) {
   9632         interlace_format->bInterlaceFormat = OMX_FALSE;
   9633         interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
   9634         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   9635     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_TOPFIELDFIRST) && !is_mbaff) {
   9636         interlace_format->bInterlaceFormat = OMX_TRUE;
   9637         interlace_format->nInterlaceFormats =  OMX_InterlaceInterleaveFrameTopFieldFirst;
   9638         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   9639     } else if ((interlaced_format_type == MSM_VIDC_INTERLACE_INTERLEAVE_FRAME_BOTTOMFIELDFIRST) && !is_mbaff) {
   9640         interlace_format->bInterlaceFormat = OMX_TRUE;
   9641         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameBottomFieldFirst;
   9642         drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
   9643     } else {
   9644         interlace_format->bInterlaceFormat = OMX_TRUE;
   9645         interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
   9646         drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
   9647     }
   9648     print_debug_extradata(extra);
   9649 }
   9650 
   9651 void omx_vdec::append_frame_dimension_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   9652 {
   9653     OMX_QCOM_EXTRADATA_FRAMEDIMENSION *frame_dimension;
   9654     if (!(client_extradata & OMX_FRAMEDIMENSION_EXTRADATA)) {
   9655         return;
   9656     }
   9657     extra->nSize = OMX_FRAMEDIMENSION_EXTRADATA_SIZE;
   9658     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9659     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9660     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameDimension;
   9661     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEDIMENSION);
   9662     frame_dimension = (OMX_QCOM_EXTRADATA_FRAMEDIMENSION *)(void *)extra->data;
   9663     frame_dimension->nDecWidth = rectangle.nLeft;
   9664     frame_dimension->nDecHeight = rectangle.nTop;
   9665     frame_dimension->nActualWidth = rectangle.nWidth;
   9666     frame_dimension->nActualHeight = rectangle.nHeight;
   9667 }
   9668 
   9669 void omx_vdec::fill_aspect_ratio_info(
   9670         struct vdec_aspectratioinfo *aspect_ratio_info,
   9671         OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
   9672 {
   9673     m_extradata = frame_info;
   9674     m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
   9675     m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
   9676     DEBUG_PRINT_LOW("aspectRatioX %u aspectRatioY %u", (unsigned int)m_extradata->aspectRatio.aspectRatioX,
   9677             (unsigned int)m_extradata->aspectRatio.aspectRatioY);
   9678 }
   9679 
   9680 void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9681         OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_U32 frame_rate,
   9682         OMX_TICKS time_stamp, struct msm_vidc_panscan_window_payload *panscan_payload,
   9683         struct vdec_aspectratioinfo *aspect_ratio_info)
   9684 {
   9685     OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
   9686     struct msm_vidc_panscan_window *panscan_window;
   9687     if (!(client_extradata & OMX_FRAMEINFO_EXTRADATA)) {
   9688         return;
   9689     }
   9690     extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
   9691     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9692     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9693     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
   9694     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
   9695     frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)(void *)extra->data;
   9696     switch (picture_type) {
   9697         case PICTURE_TYPE_I:
   9698             frame_info->ePicType = OMX_VIDEO_PictureTypeI;
   9699             break;
   9700         case PICTURE_TYPE_P:
   9701             frame_info->ePicType = OMX_VIDEO_PictureTypeP;
   9702             break;
   9703         case PICTURE_TYPE_B:
   9704             frame_info->ePicType = OMX_VIDEO_PictureTypeB;
   9705             break;
   9706         default:
   9707             frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
   9708     }
   9709     if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
   9710         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
   9711     else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
   9712         frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
   9713     else
   9714         frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
   9715     memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
   9716     frame_info->nConcealedMacroblocks = num_conceal_mb;
   9717     frame_info->nFrameRate = frame_rate;
   9718     frame_info->nTimeStamp = time_stamp;
   9719     frame_info->panScan.numWindows = 0;
   9720     if (output_capability == V4L2_PIX_FMT_MPEG2) {
   9721         if (m_disp_hor_size && m_disp_vert_size) {
   9722             frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
   9723             frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
   9724         } else {
   9725             frame_info->displayAspectRatio.displayHorizontalSize = 0;
   9726             frame_info->displayAspectRatio.displayVerticalSize = 0;
   9727         }
   9728     }
   9729 
   9730     if (panscan_payload) {
   9731         frame_info->panScan.numWindows = panscan_payload->num_panscan_windows;
   9732         panscan_window = &panscan_payload->wnd[0];
   9733         for (OMX_U32 i = 0; i < frame_info->panScan.numWindows; i++) {
   9734             frame_info->panScan.window[i].x = panscan_window->panscan_window_width;
   9735             frame_info->panScan.window[i].y = panscan_window->panscan_window_height;
   9736             frame_info->panScan.window[i].dx = panscan_window->panscan_width_offset;
   9737             frame_info->panScan.window[i].dy = panscan_window->panscan_height_offset;
   9738             panscan_window++;
   9739         }
   9740     }
   9741     fill_aspect_ratio_info(aspect_ratio_info, frame_info);
   9742     print_debug_extradata(extra);
   9743 }
   9744 
   9745 void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   9746 {
   9747     OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
   9748     extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
   9749     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9750     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9751     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
   9752     extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
   9753     portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)(void *)extra->data;
   9754     *portDefn = m_port_def;
   9755     DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u "
   9756             "stride = %u sliceheight = %u",(unsigned int)portDefn->format.video.nFrameHeight,
   9757             (unsigned int)portDefn->format.video.nFrameWidth,
   9758             (unsigned int)portDefn->format.video.nStride,
   9759             (unsigned int)portDefn->format.video.nSliceHeight);
   9760 }
   9761 
   9762 void omx_vdec::append_framepack_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9763         struct msm_vidc_s3d_frame_packing_payload *s3d_frame_packing_payload)
   9764 {
   9765     OMX_QCOM_FRAME_PACK_ARRANGEMENT *framepack;
   9766     if (FRAME_PACK_SIZE*sizeof(OMX_U32) != sizeof(struct msm_vidc_s3d_frame_packing_payload)) {
   9767         DEBUG_PRINT_ERROR("frame packing size mismatch");
   9768         return;
   9769     }
   9770     extra->nSize = OMX_FRAMEPACK_EXTRADATA_SIZE;
   9771     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9772     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9773     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFramePackingArrangement;
   9774     extra->nDataSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   9775     framepack = (OMX_QCOM_FRAME_PACK_ARRANGEMENT *)(void *)extra->data;
   9776     framepack->nSize = sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT);
   9777     framepack->nVersion.nVersion = OMX_SPEC_VERSION;
   9778     framepack->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9779     memcpy(&framepack->id, s3d_frame_packing_payload,
   9780         sizeof(struct msm_vidc_s3d_frame_packing_payload));
   9781     memcpy(&m_frame_pack_arrangement, framepack,
   9782         sizeof(OMX_QCOM_FRAME_PACK_ARRANGEMENT));
   9783     print_debug_extradata(extra);
   9784 }
   9785 
   9786 void omx_vdec::append_qp_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9787             struct msm_vidc_frame_qp_payload *qp_payload)
   9788 {
   9789     OMX_QCOM_EXTRADATA_QP * qp = NULL;
   9790     if (!qp_payload) {
   9791         DEBUG_PRINT_ERROR("QP payload is NULL");
   9792         return;
   9793     }
   9794     extra->nSize = OMX_QP_EXTRADATA_SIZE;
   9795     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9796     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9797     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataQP;
   9798     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_QP);
   9799     qp = (OMX_QCOM_EXTRADATA_QP *)(void *)extra->data;
   9800     qp->nQP = qp_payload->frame_qp;
   9801     print_debug_extradata(extra);
   9802 }
   9803 
   9804 void omx_vdec::append_bitsinfo_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9805             struct msm_vidc_frame_bits_info_payload *bits_payload)
   9806 {
   9807     OMX_QCOM_EXTRADATA_BITS_INFO * bits = NULL;
   9808     if (!bits_payload) {
   9809         DEBUG_PRINT_ERROR("bits info payload is NULL");
   9810         return;
   9811     }
   9812     extra->nSize = OMX_BITSINFO_EXTRADATA_SIZE;
   9813     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9814     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9815     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInputBitsInfo;
   9816     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_BITS_INFO);
   9817     bits = (OMX_QCOM_EXTRADATA_BITS_INFO*)(void *)extra->data;
   9818     bits->frame_bits = bits_payload->frame_bits;
   9819     bits->header_bits = bits_payload->header_bits;
   9820     print_debug_extradata(extra);
   9821 }
   9822 
   9823 void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9824             OMX_OTHER_EXTRADATATYPE *p_user)
   9825 {
   9826     int userdata_size = 0;
   9827     struct msm_vidc_stream_userdata_payload *userdata_payload = NULL;
   9828     userdata_payload =
   9829         (struct msm_vidc_stream_userdata_payload *)(void *)p_user->data;
   9830     userdata_size = p_user->nDataSize;
   9831     extra->nSize = OMX_USERDATA_EXTRADATA_SIZE + userdata_size;
   9832     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9833     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9834     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
   9835     extra->nDataSize = userdata_size;
   9836     if (extra->data && p_user->data && extra->nDataSize)
   9837         memcpy(extra->data, p_user->data, extra->nDataSize);
   9838     print_debug_extradata(extra);
   9839 }
   9840 
   9841 void omx_vdec::append_mpeg2_seqdisplay_extradata(OMX_OTHER_EXTRADATATYPE *extra,
   9842         struct msm_vidc_mpeg2_seqdisp_payload *seq_display_payload)
   9843 {
   9844     OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *seq_display = NULL;
   9845     extra->nSize = OMX_MPEG2SEQDISP_EXTRADATA_SIZE;
   9846     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9847     extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   9848     extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMpeg2SeqDisplay;
   9849     extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY);
   9850     seq_display = (OMX_QCOM_EXTRADATA_MPEG2SEQDISPLAY *)(void *)extra->data;
   9851     seq_display->disp_width = seq_display_payload->disp_width;
   9852     seq_display->disp_height = seq_display_payload->disp_height;
   9853     print_debug_extradata(extra);
   9854 }
   9855 void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
   9856 {
   9857     if (!client_extradata) {
   9858         return;
   9859     }
   9860     extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
   9861     extra->nVersion.nVersion = OMX_SPEC_VERSION;
   9862     extra->eType = OMX_ExtraDataNone;
   9863     extra->nDataSize = 0;
   9864     extra->data[0] = 0;
   9865 
   9866     print_debug_extradata(extra);
   9867 }
   9868 
   9869 OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
   9870 {
   9871     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   9872     if (index >= drv_ctx.ip_buf.actualcount) {
   9873         DEBUG_PRINT_ERROR("ERROR:Desc Buffer Index not found");
   9874         return OMX_ErrorInsufficientResources;
   9875     }
   9876     if (m_desc_buffer_ptr == NULL) {
   9877         m_desc_buffer_ptr = (desc_buffer_hdr*) \
   9878                     calloc( (sizeof(desc_buffer_hdr)),
   9879                             drv_ctx.ip_buf.actualcount);
   9880         if (m_desc_buffer_ptr == NULL) {
   9881             DEBUG_PRINT_ERROR("m_desc_buffer_ptr Allocation failed ");
   9882             return OMX_ErrorInsufficientResources;
   9883         }
   9884     }
   9885 
   9886     m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
   9887     if (m_desc_buffer_ptr[index].buf_addr == NULL) {
   9888         DEBUG_PRINT_ERROR("desc buffer Allocation failed ");
   9889         return OMX_ErrorInsufficientResources;
   9890     }
   9891 
   9892     return eRet;
   9893 }
   9894 
   9895 void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
   9896 {
   9897     DEBUG_PRINT_LOW("Inserting address offset (%u) at idx (%u)", (unsigned int)address_offset,(unsigned int)m_demux_entries);
   9898     if (m_demux_entries < 8192) {
   9899         m_demux_offsets[m_demux_entries++] = address_offset;
   9900     }
   9901     return;
   9902 }
   9903 
   9904 void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
   9905 {
   9906     OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
   9907     OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
   9908     OMX_U32 index = 0;
   9909 
   9910     m_demux_entries = 0;
   9911 
   9912     while (index < bytes_to_parse) {
   9913         if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   9914                     (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
   9915                 ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
   9916                  (buf[index+2] == 0x01)) ) {
   9917             //Found start code, insert address offset
   9918             insert_demux_addr_offset(index);
   9919             if (buf[index+2] == 0x01) // 3 byte start code
   9920                 index += 3;
   9921             else                      //4 byte start code
   9922                 index += 4;
   9923         } else
   9924             index++;
   9925     }
   9926     DEBUG_PRINT_LOW("Extracted (%u) demux entry offsets", (unsigned int)m_demux_entries);
   9927     return;
   9928 }
   9929 
   9930 OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
   9931 {
   9932     //fix this, handle 3 byte start code, vc1 terminator entry
   9933     OMX_U8 *p_demux_data = NULL;
   9934     OMX_U32 desc_data = 0;
   9935     OMX_U32 start_addr = 0;
   9936     OMX_U32 nal_size = 0;
   9937     OMX_U32 suffix_byte = 0;
   9938     OMX_U32 demux_index = 0;
   9939     OMX_U32 buffer_index = 0;
   9940 
   9941     if (m_desc_buffer_ptr == NULL) {
   9942         DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
   9943         return OMX_ErrorBadParameter;
   9944     }
   9945 
   9946     buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
   9947     if (buffer_index > drv_ctx.ip_buf.actualcount) {
   9948         DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%u)", (unsigned int)buffer_index);
   9949         return OMX_ErrorBadParameter;
   9950     }
   9951 
   9952     p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
   9953 
   9954     if ( ((OMX_U8*)p_demux_data == NULL) ||
   9955             ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
   9956         DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
   9957         return OMX_ErrorBadParameter;
   9958     } else {
   9959         for (; demux_index < m_demux_entries; demux_index++) {
   9960             desc_data = 0;
   9961             start_addr = m_demux_offsets[demux_index];
   9962             if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
   9963                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
   9964             } else {
   9965                 suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
   9966             }
   9967             if (demux_index < (m_demux_entries - 1)) {
   9968                 nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
   9969             } else {
   9970                 nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
   9971             }
   9972             DEBUG_PRINT_LOW("Start_addr(0x%x), suffix_byte(0x%x),nal_size(%u),demux_index(%u)",
   9973                     (unsigned int)start_addr,
   9974                     (unsigned int)suffix_byte,
   9975                     (unsigned int)nal_size,
   9976                     (unsigned int)demux_index);
   9977             desc_data = (start_addr >> 3) << 1;
   9978             desc_data |= (start_addr & 7) << 21;
   9979             desc_data |= suffix_byte << 24;
   9980 
   9981             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   9982             memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
   9983             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   9984             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   9985 
   9986             p_demux_data += 16;
   9987         }
   9988         if (codec_type_parse == CODEC_TYPE_VC1) {
   9989             DEBUG_PRINT_LOW("VC1 terminator entry");
   9990             desc_data = 0;
   9991             desc_data = 0x82 << 24;
   9992             memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
   9993             memset(p_demux_data + 4, 0, sizeof(OMX_U32));
   9994             memset(p_demux_data + 8, 0, sizeof(OMX_U32));
   9995             memset(p_demux_data + 12, 0, sizeof(OMX_U32));
   9996             p_demux_data += 16;
   9997             m_demux_entries++;
   9998         }
   9999         //Add zero word to indicate end of descriptors
   10000         memset(p_demux_data, 0, sizeof(OMX_U32));
   10001 
   10002         m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
   10003         DEBUG_PRINT_LOW("desc table data size=%u", (unsigned int)m_desc_buffer_ptr[buffer_index].desc_data_size);
   10004     }
   10005     memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
   10006     m_demux_entries = 0;
   10007     DEBUG_PRINT_LOW("Demux table complete!");
   10008     return OMX_ErrorNone;
   10009 }
   10010 
   10011 OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
   10012 {
   10013     OMX_ERRORTYPE err = OMX_ErrorNone;
   10014     iDivXDrmDecrypt = DivXDrmDecrypt::Create();
   10015     if (iDivXDrmDecrypt) {
   10016         OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
   10017         if (err!=OMX_ErrorNone) {
   10018             DEBUG_PRINT_ERROR("ERROR :iDivXDrmDecrypt->Init %d", err);
   10019             delete iDivXDrmDecrypt;
   10020             iDivXDrmDecrypt = NULL;
   10021         }
   10022     } else {
   10023         DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
   10024         err = OMX_ErrorUndefined;
   10025     }
   10026     return err;
   10027 }
   10028 
   10029 omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
   10030 {
   10031     enabled = false;
   10032     omx = NULL;
   10033     init_members();
   10034     ColorFormat = OMX_COLOR_FormatMax;
   10035     dest_format = YCbCr420P;
   10036 }
   10037 
   10038 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   10039 {
   10040     omx = reinterpret_cast<omx_vdec*>(client);
   10041 }
   10042 
   10043 void omx_vdec::allocate_color_convert_buf::init_members()
   10044 {
   10045     allocated_count = 0;
   10046     buffer_size_req = 0;
   10047     buffer_alignment_req = 0;
   10048     memset(m_platform_list_client,0,sizeof(m_platform_list_client));
   10049     memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
   10050     memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
   10051     memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
   10052 #ifdef USE_ION
   10053     memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
   10054 #endif
   10055     for (int i = 0; i < MAX_COUNT; i++)
   10056         pmem_fd[i] = -1;
   10057 }
   10058 
   10059 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   10060 {
   10061     c2d.destroy();
   10062 }
   10063 
   10064 bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
   10065 {
   10066     bool status = true;
   10067     unsigned int src_size = 0, destination_size = 0;
   10068     OMX_COLOR_FORMATTYPE drv_color_format;
   10069     if (!omx) {
   10070         DEBUG_PRINT_ERROR("Invalid client in color convert");
   10071         return false;
   10072     }
   10073     if (!enabled) {
   10074         DEBUG_PRINT_HIGH("No color conversion required");
   10075         return status;
   10076     }
   10077     pthread_mutex_lock(&omx->c_lock);
   10078     if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_NV12 &&
   10079             ColorFormat != OMX_COLOR_FormatYUV420Planar) {
   10080         DEBUG_PRINT_ERROR("update_buffer_req: Unsupported color conversion");
   10081         status = false;
   10082         goto fail_update_buf_req;
   10083     }
   10084     c2d.close();
   10085     status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
   10086             omx->drv_ctx.video_resolution.frame_width,
   10087             NV12_128m,dest_format);
   10088     if (status) {
   10089         status = c2d.get_buffer_size(C2D_INPUT,src_size);
   10090         if (status)
   10091             status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
   10092     }
   10093     if (status) {
   10094         if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
   10095                 !destination_size) {
   10096             DEBUG_PRINT_ERROR("ERROR: Size mismatch in C2D src_size %d"
   10097                     "driver size %u destination size %d",
   10098                     src_size, (unsigned int)omx->drv_ctx.op_buf.buffer_size,
   10099                     destination_size);
   10100             status = false;
   10101             c2d.close();
   10102             buffer_size_req = 0;
   10103         } else {
   10104             buffer_size_req = destination_size;
   10105             if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
   10106                 buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
   10107             if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   10108                 buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   10109         }
   10110     }
   10111 fail_update_buf_req:
   10112     pthread_mutex_unlock(&omx->c_lock);
   10113     return status;
   10114 }
   10115 
   10116 bool omx_vdec::allocate_color_convert_buf::set_color_format(
   10117         OMX_COLOR_FORMATTYPE dest_color_format)
   10118 {
   10119     bool status = true;
   10120     OMX_COLOR_FORMATTYPE drv_color_format;
   10121     if (!omx) {
   10122         DEBUG_PRINT_ERROR("Invalid client in color convert");
   10123         return false;
   10124     }
   10125     pthread_mutex_lock(&omx->c_lock);
   10126     if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   10127         if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   10128             drv_color_format = (OMX_COLOR_FORMATTYPE)
   10129                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   10130         else
   10131         drv_color_format = (OMX_COLOR_FORMATTYPE)
   10132             QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10133     else {
   10134         DEBUG_PRINT_ERROR("Incorrect color format");
   10135         status = false;
   10136     }
   10137     if (status && !omx->is_component_secure() &&
   10138         drv_color_format != dest_color_format &&
   10139         drv_color_format != (OMX_COLOR_FORMATTYPE)
   10140                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView) {
   10141         DEBUG_PRINT_LOW("Enabling C2D");
   10142         if ((dest_color_format != OMX_COLOR_FormatYUV420Planar) &&
   10143            (dest_color_format != OMX_COLOR_FormatYUV420SemiPlanar)) {
   10144             DEBUG_PRINT_ERROR("Unsupported color format for c2d");
   10145             status = false;
   10146         } else {
   10147             ColorFormat = dest_color_format;
   10148             dest_format = (dest_color_format == OMX_COLOR_FormatYUV420Planar) ?
   10149                     YCbCr420P : YCbCr420SP;
   10150             if (enabled)
   10151                 c2d.destroy();
   10152             enabled = false;
   10153             if (!c2d.init()) {
   10154                 DEBUG_PRINT_ERROR("open failed for c2d");
   10155                 status = false;
   10156             } else
   10157                 enabled = true;
   10158         }
   10159     } else {
   10160         if (enabled)
   10161             c2d.destroy();
   10162         enabled = false;
   10163     }
   10164     pthread_mutex_unlock(&omx->c_lock);
   10165     return status;
   10166 }
   10167 
   10168 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   10169 {
   10170     if (!omx) {
   10171         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   10172         return NULL;
   10173     }
   10174     if (!enabled)
   10175         return omx->m_out_mem_ptr;
   10176     return m_out_mem_ptr_client;
   10177 }
   10178 
   10179     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
   10180 (OMX_BUFFERHEADERTYPE *bufadd)
   10181 {
   10182     if (!omx) {
   10183         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   10184         return NULL;
   10185     }
   10186     if (!enabled)
   10187         return bufadd;
   10188 
   10189     unsigned index = 0;
   10190     index = bufadd - omx->m_out_mem_ptr;
   10191     if (index < omx->drv_ctx.op_buf.actualcount) {
   10192         m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
   10193         m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
   10194         bool status;
   10195         if (!omx->in_reconfig && !omx->output_flush_progress && bufadd->nFilledLen) {
   10196             pthread_mutex_lock(&omx->c_lock);
   10197             cache_clean_buffer(index);
   10198             status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
   10199                     omx->m_out_mem_ptr->pBuffer, bufadd->pBuffer, pmem_fd[index],
   10200                     pmem_baseaddress[index], pmem_baseaddress[index]);
   10201             if (!status) {
   10202                 DEBUG_PRINT_ERROR("Failed color conversion %d", status);
   10203                 m_out_mem_ptr_client[index].nFilledLen = 0;
   10204                 pthread_mutex_unlock(&omx->c_lock);
   10205                 return &m_out_mem_ptr_client[index];
   10206             } else {
   10207                 unsigned int filledLen = 0;
   10208                 c2d.get_output_filled_length(filledLen);
   10209                 m_out_mem_ptr_client[index].nFilledLen = filledLen;
   10210                 cache_clean_invalidate_buffer(index);
   10211             }
   10212             pthread_mutex_unlock(&omx->c_lock);
   10213         } else
   10214             m_out_mem_ptr_client[index].nFilledLen = 0;
   10215         return &m_out_mem_ptr_client[index];
   10216     }
   10217     DEBUG_PRINT_ERROR("Index messed up in the get_il_buf_hdr");
   10218     return NULL;
   10219 }
   10220 
   10221     OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
   10222 (OMX_BUFFERHEADERTYPE *bufadd)
   10223 {
   10224     if (!omx) {
   10225         DEBUG_PRINT_ERROR("Invalid param get_buf_hdr");
   10226         return NULL;
   10227     }
   10228     if (!enabled)
   10229         return bufadd;
   10230     unsigned index = 0;
   10231     index = bufadd - m_out_mem_ptr_client;
   10232     if (index < omx->drv_ctx.op_buf.actualcount) {
   10233         return &omx->m_out_mem_ptr[index];
   10234     }
   10235     DEBUG_PRINT_ERROR("Index messed up in the get_dr_buf_hdr");
   10236     return NULL;
   10237 }
   10238     bool omx_vdec::allocate_color_convert_buf::get_buffer_req
   10239 (unsigned int &buffer_size)
   10240 {
   10241     bool status = true;
   10242     pthread_mutex_lock(&omx->c_lock);
   10243     if (!enabled)
   10244         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   10245     else {
   10246         if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
   10247             DEBUG_PRINT_ERROR("Get buffer size failed");
   10248             status = false;
   10249             goto fail_get_buffer_size;
   10250         }
   10251     }
   10252     if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
   10253         buffer_size = omx->drv_ctx.op_buf.buffer_size;
   10254     if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
   10255         buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
   10256 fail_get_buffer_size:
   10257     pthread_mutex_unlock(&omx->c_lock);
   10258     return status;
   10259 }
   10260 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
   10261         OMX_BUFFERHEADERTYPE *bufhdr)
   10262 {
   10263     unsigned int index = 0;
   10264 
   10265     if (!enabled)
   10266         return omx->free_output_buffer(bufhdr);
   10267     if (enabled && omx->is_component_secure())
   10268         return OMX_ErrorNone;
   10269     if (!allocated_count || !bufhdr) {
   10270         DEBUG_PRINT_ERROR("Color convert no buffer to be freed %p",bufhdr);
   10271         return OMX_ErrorBadParameter;
   10272     }
   10273     index = bufhdr - m_out_mem_ptr_client;
   10274     if (index >= omx->drv_ctx.op_buf.actualcount) {
   10275         DEBUG_PRINT_ERROR("Incorrect index color convert free_output_buffer");
   10276         return OMX_ErrorBadParameter;
   10277     }
   10278     if (pmem_fd[index] > 0) {
   10279         munmap(pmem_baseaddress[index], buffer_size_req);
   10280         close(pmem_fd[index]);
   10281     }
   10282     pmem_fd[index] = -1;
   10283 #ifdef USE_ION
   10284     omx->free_ion_memory(&op_buf_ion_info[index]);
   10285 #endif
   10286     m_heap_ptr[index].video_heap_ptr = NULL;
   10287     if (allocated_count > 0)
   10288         allocated_count--;
   10289     else
   10290         allocated_count = 0;
   10291     if (!allocated_count) {
   10292         pthread_mutex_lock(&omx->c_lock);
   10293         c2d.close();
   10294         init_members();
   10295         pthread_mutex_unlock(&omx->c_lock);
   10296     }
   10297     return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
   10298 }
   10299 
   10300 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
   10301         OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
   10302 {
   10303     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10304     if (!enabled) {
   10305         eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
   10306         return eRet;
   10307     }
   10308     if (enabled && omx->is_component_secure()) {
   10309         DEBUG_PRINT_ERROR("Notin color convert mode secure_mode %d",
   10310                 omx->is_component_secure());
   10311         return OMX_ErrorUnsupportedSetting;
   10312     }
   10313     if (!bufferHdr || bytes > buffer_size_req) {
   10314         DEBUG_PRINT_ERROR("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   10315         DEBUG_PRINT_ERROR("color_convert buffer_size_req %u bytes %u",
   10316                 (unsigned int)buffer_size_req, (unsigned int)bytes);
   10317         return OMX_ErrorBadParameter;
   10318     }
   10319     if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
   10320         DEBUG_PRINT_ERROR("Actual count err in allocate_buffers_color_convert");
   10321         return OMX_ErrorInsufficientResources;
   10322     }
   10323     OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
   10324     eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
   10325             port,appData,omx->drv_ctx.op_buf.buffer_size);
   10326     if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
   10327         DEBUG_PRINT_ERROR("Buffer allocation failed color_convert");
   10328         return eRet;
   10329     }
   10330     if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
   10331             (int)omx->drv_ctx.op_buf.actualcount) {
   10332         DEBUG_PRINT_ERROR("Invalid header index %ld",
   10333                (long int)(temp_bufferHdr - omx->m_out_mem_ptr));
   10334         return OMX_ErrorUndefined;
   10335     }
   10336     unsigned int i = allocated_count;
   10337 #ifdef USE_ION
   10338     // Allocate color-conversion buffers as cached to improve software-reading
   10339     // performance of YUV (thumbnails). NOTE: These buffers will need an explicit
   10340     // cache invalidation.
   10341     op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
   10342             buffer_size_req,buffer_alignment_req,
   10343             &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
   10344             ION_FLAG_CACHED);
   10345     pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
   10346     if (op_buf_ion_info[i].ion_device_fd < 0) {
   10347         DEBUG_PRINT_ERROR("alloc_map_ion failed in color_convert");
   10348         return OMX_ErrorInsufficientResources;
   10349     }
   10350     pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
   10351             PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
   10352 
   10353     if (pmem_baseaddress[i] == MAP_FAILED) {
   10354         DEBUG_PRINT_ERROR("MMAP failed for Size %d",buffer_size_req);
   10355         close(pmem_fd[i]);
   10356         omx->free_ion_memory(&op_buf_ion_info[i]);
   10357         return OMX_ErrorInsufficientResources;
   10358     }
   10359     m_heap_ptr[i].video_heap_ptr = new VideoHeap (
   10360             op_buf_ion_info[i].ion_device_fd,buffer_size_req,
   10361             pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
   10362 #endif
   10363     m_pmem_info_client[i].pmem_fd = (unsigned long)m_heap_ptr[i].video_heap_ptr.get();
   10364     m_pmem_info_client[i].offset = 0;
   10365     m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
   10366     m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
   10367     m_platform_list_client[i].nEntries = 1;
   10368     m_platform_list_client[i].entryList = &m_platform_entry_client[i];
   10369     m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
   10370     m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
   10371     m_out_mem_ptr_client[i].nFilledLen = 0;
   10372     m_out_mem_ptr_client[i].nFlags = 0;
   10373     m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
   10374     m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
   10375     m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
   10376     m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
   10377     m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
   10378     m_out_mem_ptr_client[i].pAppPrivate = appData;
   10379     *bufferHdr = &m_out_mem_ptr_client[i];
   10380     DEBUG_PRINT_HIGH("IL client buffer header %p", *bufferHdr);
   10381     allocated_count++;
   10382     return eRet;
   10383 }
   10384 
   10385 bool omx_vdec::is_component_secure()
   10386 {
   10387     return secure_mode;
   10388 }
   10389 
   10390 bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
   10391 {
   10392     bool status = true;
   10393     if (!enabled) {
   10394         if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
   10395             if (omx->drv_ctx.decoder_format == VDEC_CODECTYPE_MVC)
   10396                     dest_color_format = (OMX_COLOR_FORMATTYPE)
   10397                         QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mMultiView;
   10398                 else
   10399             dest_color_format =  (OMX_COLOR_FORMATTYPE)
   10400                 QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m;
   10401         else
   10402             status = false;
   10403     } else {
   10404         if (ColorFormat == OMX_COLOR_FormatYUV420Planar ||
   10405             ColorFormat == OMX_COLOR_FormatYUV420SemiPlanar) {
   10406             dest_color_format = ColorFormat;
   10407         } else
   10408             status = false;
   10409     }
   10410     return status;
   10411 }
   10412 
   10413 OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::cache_ops(
   10414         unsigned int index, unsigned int cmd)
   10415 {
   10416     if (!enabled) {
   10417         return OMX_ErrorNone;
   10418     }
   10419 
   10420     if (!omx || index >= omx->drv_ctx.op_buf.actualcount) {
   10421         DEBUG_PRINT_ERROR("%s: Invalid param", __func__);
   10422         return OMX_ErrorBadParameter;
   10423     }
   10424 
   10425     struct ion_flush_data flush_data;
   10426     struct ion_custom_data custom_data;
   10427 
   10428     memset(&flush_data, 0x0, sizeof(flush_data));
   10429     memset(&custom_data, 0x0, sizeof(custom_data));
   10430 
   10431     flush_data.vaddr = pmem_baseaddress[index];
   10432     flush_data.fd = op_buf_ion_info[index].fd_ion_data.fd;
   10433     flush_data.handle = op_buf_ion_info[index].fd_ion_data.handle;
   10434     flush_data.length = buffer_size_req;
   10435     custom_data.cmd = cmd;
   10436     custom_data.arg = (unsigned long)&flush_data;
   10437 
   10438     DEBUG_PRINT_LOW("Cache %s: fd=%d handle=%d va=%p size=%d",
   10439             (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   10440             flush_data.fd, flush_data.handle, flush_data.vaddr,
   10441             flush_data.length);
   10442     int ret = ioctl(op_buf_ion_info[index].ion_device_fd, ION_IOC_CUSTOM, &custom_data);
   10443     if (ret < 0) {
   10444         DEBUG_PRINT_ERROR("Cache %s failed: %s\n",
   10445                 (cmd == ION_IOC_CLEAN_CACHES) ? "Clean" : "Invalidate",
   10446                 strerror(errno));
   10447         return OMX_ErrorUndefined;
   10448     }
   10449     return OMX_ErrorNone;
   10450 }
   10451 
   10452 void omx_vdec::buf_ref_add(OMX_U32 fd, OMX_U32 offset)
   10453 {
   10454     unsigned long i = 0;
   10455     bool buf_present = false;
   10456 
   10457     if (!dynamic_buf_mode) {
   10458         return;
   10459     }
   10460 
   10461     if (!out_dynamic_list) {
   10462         DEBUG_PRINT_ERROR("buf_ref_add: out_dynamic_list is NULL");
   10463         return;
   10464     }
   10465 
   10466     pthread_mutex_lock(&m_lock);
   10467     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   10468         //check the buffer fd, offset, uv addr with list contents
   10469         //If present increment reference.
   10470         if ((out_dynamic_list[i].fd == fd) &&
   10471             (out_dynamic_list[i].offset == offset)) {
   10472                out_dynamic_list[i].ref_count++;
   10473                DEBUG_PRINT_LOW("buf_ref_add: [ALREADY PRESENT] fd = %u ref_count = %u",
   10474                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   10475                buf_present = true;
   10476                break;
   10477         }
   10478     }
   10479     if (!buf_present) {
   10480         for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   10481             //search for a entry to insert details of the new buffer
   10482             if (out_dynamic_list[i].dup_fd == 0) {
   10483                 out_dynamic_list[i].fd = fd;
   10484                 out_dynamic_list[i].offset = offset;
   10485                 out_dynamic_list[i].dup_fd = dup(fd);
   10486                 out_dynamic_list[i].ref_count++;
   10487                 DEBUG_PRINT_LOW("buf_ref_add: [ADDED] fd = %u ref_count = %u",
   10488                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   10489                 break;
   10490             }
   10491         }
   10492     }
   10493    pthread_mutex_unlock(&m_lock);
   10494 }
   10495 
   10496 void omx_vdec::buf_ref_remove(OMX_U32 fd, OMX_U32 offset)
   10497 {
   10498     unsigned long i = 0;
   10499 
   10500     if (!dynamic_buf_mode) {
   10501         return;
   10502     }
   10503 
   10504     if (!out_dynamic_list) {
   10505         DEBUG_PRINT_ERROR("buf_ref_add: out_dynamic_list is NULL");
   10506         return;
   10507     }
   10508 
   10509     pthread_mutex_lock(&m_lock);
   10510     for (i = 0; i < drv_ctx.op_buf.actualcount; i++) {
   10511         //check the buffer fd, offset, uv addr with list contents
   10512         //If present decrement reference.
   10513         if ((out_dynamic_list[i].fd == fd) &&
   10514             (out_dynamic_list[i].offset == offset)) {
   10515             out_dynamic_list[i].ref_count--;
   10516             if (out_dynamic_list[i].ref_count == 0) {
   10517                 close(out_dynamic_list[i].dup_fd);
   10518                 DEBUG_PRINT_LOW("buf_ref_remove: [REMOVED] fd = %u ref_count = %u",
   10519                      (unsigned int)out_dynamic_list[i].fd, (unsigned int)out_dynamic_list[i].ref_count);
   10520                 out_dynamic_list[i].dup_fd = 0;
   10521                 out_dynamic_list[i].fd = 0;
   10522                 out_dynamic_list[i].offset = 0;
   10523             }
   10524             break;
   10525         }
   10526     }
   10527     if (i  >= drv_ctx.op_buf.actualcount) {
   10528         DEBUG_PRINT_ERROR("Error - could not remove ref, no match with any entry in list");
   10529     }
   10530     pthread_mutex_unlock(&m_lock);
   10531 }
   10532 
   10533 #ifdef _MSM8974_
   10534 void omx_vdec::send_codec_config() {
   10535     if (codec_config_flag) {
   10536         unsigned long p1 = 0; // Parameter - 1
   10537         unsigned long p2 = 0; // Parameter - 2
   10538         unsigned long ident = 0;
   10539         pthread_mutex_lock(&m_lock);
   10540         DEBUG_PRINT_LOW("\n Check Queue for codec_config buffer \n");
   10541         while (m_etb_q.m_size) {
   10542             m_etb_q.pop_entry(&p1,&p2,&ident);
   10543             if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
   10544                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   10545                     if (empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
   10546                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   10547                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
   10548                         omx_report_error();
   10549                     }
   10550                 } else {
   10551                     DEBUG_PRINT_LOW("\n Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
   10552                     m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
   10553                 }
   10554             } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
   10555                 if (((OMX_BUFFERHEADERTYPE *)p2)->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
   10556                     if (empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
   10557                                 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
   10558                         DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
   10559                         omx_report_error ();
   10560                     }
   10561                 } else {
   10562                     pending_input_buffers++;
   10563                     DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
   10564                             (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
   10565                     empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
   10566                 }
   10567             } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
   10568                 DEBUG_PRINT_LOW("\n Flush Input OMX_COMPONENT_GENERATE_EBD %p",
   10569                         (OMX_BUFFERHEADERTYPE *)p1);
   10570                 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
   10571             }
   10572         }
   10573         pthread_mutex_unlock(&m_lock);
   10574     }
   10575 }
   10576 #endif
   10577 
   10578 omx_vdec::perf_control::perf_control ()
   10579 {
   10580     m_perf_lib = NULL;
   10581     m_perf_handle = -1;
   10582     m_perf_lock_acquire = NULL;
   10583     m_perf_lock_release = NULL;
   10584 }
   10585 
   10586 omx_vdec::perf_control::~perf_control()
   10587 {
   10588     if (m_perf_handle >= 0 && m_perf_lock_release) {
   10589         DEBUG_PRINT_LOW("NOTE2: release perf lock");
   10590         m_perf_lock_release(m_perf_handle);
   10591     }
   10592     if (m_perf_lib) {
   10593         dlclose(m_perf_lib);
   10594     }
   10595 }
   10596 
   10597 void omx_vdec::perf_control::request_cores(int frame_duration_us)
   10598 {
   10599     if (frame_duration_us > MIN_FRAME_DURATION_FOR_PERF_REQUEST_US) {
   10600         return;
   10601     }
   10602     load_lib();
   10603     if (m_perf_lock_acquire && m_perf_handle < 0) {
   10604         int arg = 0x700 /*base value*/ + 2 /*cores*/;
   10605         m_perf_handle = m_perf_lock_acquire(m_perf_handle, 0, &arg, sizeof(arg)/sizeof(int));
   10606         if (m_perf_handle) {
   10607             DEBUG_PRINT_HIGH("perf lock acquired");
   10608         }
   10609     }
   10610 }
   10611 
   10612 void omx_vdec::perf_control::load_lib()
   10613 {
   10614     char perf_lib_path[PROPERTY_VALUE_MAX] = {0};
   10615     if (m_perf_lib)
   10616         return;
   10617 
   10618     if((property_get("ro.vendor.extension_library", perf_lib_path, NULL) <= 0)) {
   10619         DEBUG_PRINT_ERROR("vendor library not set in ro.vendor.extension_library");
   10620         return;
   10621     }
   10622 
   10623     if ((m_perf_lib = dlopen(perf_lib_path, RTLD_NOW)) == NULL) {
   10624         DEBUG_PRINT_ERROR("Failed to open %s : %s",perf_lib_path, dlerror());
   10625     } else {
   10626         m_perf_lock_acquire = (perf_lock_acquire_t)dlsym(m_perf_lib, "perf_lock_acq");
   10627         if (m_perf_lock_acquire == NULL) {
   10628             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_acq");
   10629         }
   10630         m_perf_lock_release = (perf_lock_release_t)dlsym(m_perf_lib, "perf_lock_rel");
   10631         if (m_perf_lock_release == NULL) {
   10632             DEBUG_PRINT_ERROR("Failed to load symbol: perf_lock_rel");
   10633         }
   10634     }
   10635 }
   10636 
   10637 OMX_ERRORTYPE omx_vdec::enable_adaptive_playback(unsigned long nMaxFrameWidth,
   10638                             unsigned long nMaxFrameHeight)
   10639 {
   10640 
   10641     OMX_ERRORTYPE eRet = OMX_ErrorNone;
   10642     int ret = 0;
   10643     unsigned long min_res_buf_count = 0;
   10644 
   10645     eRet = enable_smoothstreaming();
   10646     if (eRet != OMX_ErrorNone) {
   10647          DEBUG_PRINT_ERROR("Failed to enable Adaptive Playback on driver");
   10648          return eRet;
   10649      }
   10650 
   10651      DEBUG_PRINT_HIGH("Enabling Adaptive playback for %lu x %lu",
   10652              nMaxFrameWidth,
   10653              nMaxFrameHeight);
   10654      m_smoothstreaming_mode = true;
   10655      m_smoothstreaming_width = nMaxFrameWidth;
   10656      m_smoothstreaming_height = nMaxFrameHeight;
   10657 
   10658      //Get upper limit buffer count for min supported resolution
   10659      struct v4l2_format fmt;
   10660      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10661      fmt.fmt.pix_mp.height = m_decoder_capability.min_height;
   10662      fmt.fmt.pix_mp.width = m_decoder_capability.min_width;
   10663      fmt.fmt.pix_mp.pixelformat = output_capability;
   10664 
   10665      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10666      if (ret) {
   10667          DEBUG_PRINT_ERROR("Set Resolution failed for HxW = %ux%u",
   10668                            m_decoder_capability.min_height,
   10669                            m_decoder_capability.min_width);
   10670          return OMX_ErrorUnsupportedSetting;
   10671      }
   10672 
   10673      eRet = get_buffer_req(&drv_ctx.op_buf);
   10674      if (eRet != OMX_ErrorNone) {
   10675          DEBUG_PRINT_ERROR("failed to get_buffer_req");
   10676          return eRet;
   10677      }
   10678 
   10679      min_res_buf_count = drv_ctx.op_buf.mincount;
   10680      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer count = %lu for HxW %ux%u",
   10681                      min_res_buf_count, m_decoder_capability.min_height, m_decoder_capability.min_width);
   10682 
   10683      update_resolution(m_smoothstreaming_width, m_smoothstreaming_height,
   10684                        m_smoothstreaming_width, m_smoothstreaming_height);
   10685      eRet = is_video_session_supported();
   10686      if (eRet != OMX_ErrorNone) {
   10687          DEBUG_PRINT_ERROR("video session is not supported");
   10688          return eRet;
   10689      }
   10690 
   10691      //Get upper limit buffer size for max smooth streaming resolution set
   10692      fmt.type = V4L2_BUF_TYPE_VIDEO_OUTPUT_MPLANE;
   10693      fmt.fmt.pix_mp.height = drv_ctx.video_resolution.frame_height;
   10694      fmt.fmt.pix_mp.width = drv_ctx.video_resolution.frame_width;
   10695      fmt.fmt.pix_mp.pixelformat = output_capability;
   10696      ret = ioctl(drv_ctx.video_driver_fd, VIDIOC_S_FMT, &fmt);
   10697      if (ret) {
   10698          DEBUG_PRINT_ERROR("Set Resolution failed for adaptive playback");
   10699          return OMX_ErrorUnsupportedSetting;
   10700      }
   10701 
   10702      eRet = get_buffer_req(&drv_ctx.op_buf);
   10703      if (eRet != OMX_ErrorNone) {
   10704          DEBUG_PRINT_ERROR("failed to get_buffer_req!!");
   10705          return eRet;
   10706      }
   10707      DEBUG_PRINT_LOW("enable adaptive - upper limit buffer size = %u",
   10708                      (unsigned int)drv_ctx.op_buf.buffer_size);
   10709 
   10710      drv_ctx.op_buf.mincount = min_res_buf_count;
   10711      drv_ctx.op_buf.actualcount = min_res_buf_count;
   10712      eRet = set_buffer_req(&drv_ctx.op_buf);
   10713      if (eRet != OMX_ErrorNone) {
   10714          DEBUG_PRINT_ERROR("failed to set_buffer_req");
   10715          return eRet;
   10716      }
   10717 
   10718      eRet = get_buffer_req(&drv_ctx.op_buf);
   10719      if (eRet != OMX_ErrorNone) {
   10720          DEBUG_PRINT_ERROR("failed to get_buffer_req!!!");
   10721          return eRet;
   10722      }
   10723      DEBUG_PRINT_HIGH("adaptive playback enabled, buf count = %u bufsize = %u",
   10724                       drv_ctx.op_buf.mincount, (unsigned int)drv_ctx.op_buf.buffer_size);
   10725      return eRet;
   10726 }
   10727 
   10728 //static
   10729 OMX_ERRORTYPE omx_vdec::describeColorFormat(OMX_PTR pParam) {
   10730 
   10731 #ifndef FLEXYUV_SUPPORTED
   10732     (void) pParam;
   10733     return OMX_ErrorUndefined;
   10734 #else
   10735 
   10736     if (pParam == NULL) {
   10737         DEBUG_PRINT_ERROR("describeColorFormat: invalid params");
   10738         return OMX_ErrorBadParameter;
   10739     }
   10740 
   10741     DescribeColorFormatParams *params = (DescribeColorFormatParams*)pParam;
   10742 
   10743     MediaImage *img = &(params->sMediaImage);
   10744     switch(params->eColorFormat) {
   10745         case QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m:
   10746         {
   10747             img->mType = MediaImage::MEDIA_IMAGE_TYPE_YUV;
   10748             img->mNumPlanes = 3;
   10749             // mWidth and mHeight represent the W x H of the largest plane
   10750             // In our case, this happens to be the Stride x Scanlines of Y plane
   10751             img->mWidth = params->nFrameWidth;
   10752             img->mHeight = params->nFrameHeight;
   10753             size_t planeWidth = VENUS_Y_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   10754             size_t planeHeight = VENUS_Y_SCANLINES(COLOR_FMT_NV12, params->nFrameHeight);
   10755             img->mBitDepth = 8;
   10756             //Plane 0 (Y)
   10757             img->mPlane[MediaImage::Y].mOffset = 0;
   10758             img->mPlane[MediaImage::Y].mColInc = 1;
   10759             img->mPlane[MediaImage::Y].mRowInc = planeWidth; //same as stride
   10760             img->mPlane[MediaImage::Y].mHorizSubsampling = 1;
   10761             img->mPlane[MediaImage::Y].mVertSubsampling = 1;
   10762             //Plane 1 (U)
   10763             img->mPlane[MediaImage::U].mOffset = planeWidth * planeHeight;
   10764             img->mPlane[MediaImage::U].mColInc = 2;           //interleaved UV
   10765             img->mPlane[MediaImage::U].mRowInc =
   10766                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   10767             img->mPlane[MediaImage::U].mHorizSubsampling = 2;
   10768             img->mPlane[MediaImage::U].mVertSubsampling = 2;
   10769             //Plane 2 (V)
   10770             img->mPlane[MediaImage::V].mOffset = planeWidth * planeHeight + 1;
   10771             img->mPlane[MediaImage::V].mColInc = 2;           //interleaved UV
   10772             img->mPlane[MediaImage::V].mRowInc =
   10773                     VENUS_UV_STRIDE(COLOR_FMT_NV12, params->nFrameWidth);
   10774             img->mPlane[MediaImage::V].mHorizSubsampling = 2;
   10775             img->mPlane[MediaImage::V].mVertSubsampling = 2;
   10776             break;
   10777         }
   10778 
   10779         case OMX_COLOR_FormatYUV420Planar:
   10780         case OMX_COLOR_FormatYUV420SemiPlanar:
   10781             // We need not describe the standard OMX linear formats as these are
   10782             // understood by client. Fail this deliberately to let client fill-in
   10783             return OMX_ErrorUnsupportedSetting;
   10784 
   10785         default:
   10786             // Rest all formats which are non-linear cannot be described
   10787             DEBUG_PRINT_LOW("color-format %x is not flexible", params->eColorFormat);
   10788             img->mType = MediaImage::MEDIA_IMAGE_TYPE_UNKNOWN;
   10789             return OMX_ErrorNone;
   10790     };
   10791 
   10792     DEBUG_PRINT_LOW("NOTE: Describe color format : %x", params->eColorFormat);
   10793     DEBUG_PRINT_LOW("  FrameWidth x FrameHeight : %d x %d", params->nFrameWidth, params->nFrameHeight);
   10794     DEBUG_PRINT_LOW("  YWidth x YHeight : %d x %d", img->mWidth, img->mHeight);
   10795     for (size_t i = 0; i < img->mNumPlanes; ++i) {
   10796         DEBUG_PRINT_LOW("    Plane[%d] : offset=%d / xStep=%d / yStep = %d",
   10797                 i, img->mPlane[i].mOffset, img->mPlane[i].mColInc, img->mPlane[i].mRowInc);
   10798     }
   10799     return OMX_ErrorNone;
   10800 #endif //FLEXYUV_SUPPORTED
   10801 }
   10802