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