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