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