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