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