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