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