1/*--------------------------------------------------------------------------
2Copyright (c) 2012, Code Aurora Forum. All rights reserved.
3
4Redistribution and use in source and binary forms, with or without
5modification, 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
16THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26ADVISED 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
80FILE *inputBufferFile1;
81char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
82#endif
83#ifdef OUTPUT_BUFFER_LOG
84FILE *outputBufferFile1;
85char outputfilename [] = "/data/output.yuv";
86#endif
87#ifdef OUTPUT_EXTRADATA_LOG
88FILE *outputExtradataFile;
89char 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
124void* 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
208void* 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
240void 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
249omx_vdec::omx_cmd_queue::~omx_cmd_queue()
250{
251  // Nothing to do
252}
253
254// omx cmd queue constructor
255omx_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
261bool 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
285bool 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
309unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
310{
311    return m_q[m_read].id;
312}
313
314#ifdef _ANDROID_
315omx_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}
320omx_vdec::ts_arr_list::~ts_arr_list()
321{
322  //free m_ts_arr_list?
323}
324
325bool 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
353bool 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
401bool 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
416void *get_omx_component_factory_fn(void)
417{
418  return (new omx_vdec);
419}
420
421#ifdef _ANDROID_
422#ifdef USE_ION
423VideoHeap::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
429VideoHeap::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/* ======================================================================
437FUNCTION
438  omx_vdec::omx_vdec
439
440DESCRIPTION
441  Constructor
442
443PARAMETERS
444  None
445
446RETURN VALUE
447  None.
448========================================================================== */
449omx_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/* ======================================================================
565FUNCTION
566  omx_vdec::~omx_vdec
567
568DESCRIPTION
569  Destructor
570
571PARAMETERS
572  None
573
574RETURN VALUE
575  None.
576========================================================================== */
577omx_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/* ======================================================================
601FUNCTION
602  omx_vdec::OMXCntrlProcessMsgCb
603
604DESCRIPTION
605  IL Client callbacks are generated through this routine. The decoder
606  provides the thread context for this routine.
607
608PARAMETERS
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
615RETURN VALUE
616  None.
617
618========================================================================== */
619void 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/* ======================================================================
1167FUNCTION
1168  omx_vdec::ComponentInit
1169
1170DESCRIPTION
1171  Initialize the component.
1172
1173PARAMETERS
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
1180RETURN VALUE
1181  None.
1182
1183========================================================================== */
1184OMX_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/* ======================================================================
1546FUNCTION
1547  omx_vdec::GetComponentVersion
1548
1549DESCRIPTION
1550  Returns the component version.
1551
1552PARAMETERS
1553  TBD.
1554
1555RETURN VALUE
1556  OMX_ErrorNone.
1557
1558========================================================================== */
1559OMX_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/* ======================================================================
1581FUNCTION
1582  omx_vdec::SendCommand
1583
1584DESCRIPTION
1585  Returns zero if all the buffers released..
1586
1587PARAMETERS
1588  None.
1589
1590RETURN VALUE
1591  true/false
1592
1593========================================================================== */
1594OMX_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/* ======================================================================
1620FUNCTION
1621  omx_vdec::SendCommand
1622
1623DESCRIPTION
1624  Returns zero if all the buffers released..
1625
1626PARAMETERS
1627  None.
1628
1629RETURN VALUE
1630  true/false
1631
1632========================================================================== */
1633OMX_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/* ======================================================================
2192FUNCTION
2193  omx_vdec::ExecuteOmxFlush
2194
2195DESCRIPTION
2196  Executes the OMX flush.
2197
2198PARAMETERS
2199  flushtype - input flush(1)/output flush(0)/ both.
2200
2201RETURN VALUE
2202  true/false
2203
2204========================================================================== */
2205bool 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/*=========================================================================
2235FUNCTION : execute_output_flush
2236
2237DESCRIPTION
2238  Executes the OMX flush at OUTPUT PORT.
2239
2240PARAMETERS
2241  None.
2242
2243RETURN VALUE
2244  true/false
2245==========================================================================*/
2246bool 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/*=========================================================================
2284FUNCTION : execute_input_flush
2285
2286DESCRIPTION
2287  Executes the OMX flush at INPUT PORT.
2288
2289PARAMETERS
2290  None.
2291
2292RETURN VALUE
2293  true/false
2294==========================================================================*/
2295bool 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/* ======================================================================
2389FUNCTION
2390  omx_vdec::SendCommandEvent
2391
2392DESCRIPTION
2393  Send the event to decoder pipe.  This is needed to generate the callbacks
2394  in decoder thread context.
2395
2396PARAMETERS
2397  None.
2398
2399RETURN VALUE
2400  true/false
2401
2402========================================================================== */
2403bool 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
2437OMX_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/* ======================================================================
2528FUNCTION
2529  omx_vdec::GetParameter
2530
2531DESCRIPTION
2532  OMX Get Parameter method implementation
2533
2534PARAMETERS
2535  <TBD>.
2536
2537RETURN VALUE
2538  Error None if successful.
2539
2540========================================================================== */
2541OMX_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_)
2776OMX_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/* ======================================================================
2808FUNCTION
2809  omx_vdec::Setparameter
2810
2811DESCRIPTION
2812  OMX Set Parameter method implementation.
2813
2814PARAMETERS
2815  <TBD>.
2816
2817RETURN VALUE
2818  OMX Error None if successful.
2819
2820========================================================================== */
2821OMX_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/* ======================================================================
3399FUNCTION
3400  omx_vdec::GetConfig
3401
3402DESCRIPTION
3403  OMX Get Config Method implementation.
3404
3405PARAMETERS
3406  <TBD>.
3407
3408RETURN VALUE
3409  OMX Error None if successful.
3410
3411========================================================================== */
3412OMX_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/* ======================================================================
3501FUNCTION
3502  omx_vdec::SetConfig
3503
3504DESCRIPTION
3505  OMX Set Config method implementation
3506
3507PARAMETERS
3508  <TBD>.
3509
3510RETURN VALUE
3511  OMX Error None if successful.
3512========================================================================== */
3513OMX_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/* ======================================================================
3668FUNCTION
3669  omx_vdec::GetExtensionIndex
3670
3671DESCRIPTION
3672  OMX GetExtensionIndex method implementaion.  <TBD>
3673
3674PARAMETERS
3675  <TBD>.
3676
3677RETURN VALUE
3678  OMX Error None if everything successful.
3679
3680========================================================================== */
3681OMX_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/* ======================================================================
3720FUNCTION
3721  omx_vdec::GetState
3722
3723DESCRIPTION
3724  Returns the state information back to the caller.<TBD>
3725
3726PARAMETERS
3727  <TBD>.
3728
3729RETURN VALUE
3730  Error None if everything is successful.
3731========================================================================== */
3732OMX_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/* ======================================================================
3741FUNCTION
3742  omx_vdec::ComponentTunnelRequest
3743
3744DESCRIPTION
3745  OMX Component Tunnel Request method implementation. <TBD>
3746
3747PARAMETERS
3748  None.
3749
3750RETURN VALUE
3751  OMX Error None if everything successful.
3752
3753========================================================================== */
3754OMX_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/* ======================================================================
3765FUNCTION
3766  omx_vdec::UseOutputBuffer
3767
3768DESCRIPTION
3769  Helper function for Use buffer in the input pin
3770
3771PARAMETERS
3772  None.
3773
3774RETURN VALUE
3775  true/false
3776
3777========================================================================== */
3778OMX_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/* ======================================================================
3959FUNCTION
3960  omx_vdec::use_input_heap_buffers
3961
3962DESCRIPTION
3963  OMX Use Buffer Heap allocation method implementation.
3964
3965PARAMETERS
3966  <TBD>.
3967
3968RETURN VALUE
3969  OMX Error None , if everything successful.
3970
3971========================================================================== */
3972OMX_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/* ======================================================================
4023FUNCTION
4024  omx_vdec::UseBuffer
4025
4026DESCRIPTION
4027  OMX Use Buffer method implementation.
4028
4029PARAMETERS
4030  <TBD>.
4031
4032RETURN VALUE
4033  OMX Error None , if everything successful.
4034
4035========================================================================== */
4036OMX_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
4099OMX_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
4113OMX_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
4167OMX_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
4230OMX_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/* ======================================================================
4313FUNCTION
4314  omx_vdec::AllocateInputBuffer
4315
4316DESCRIPTION
4317  Helper function for allocate buffer in the input pin
4318
4319PARAMETERS
4320  None.
4321
4322RETURN VALUE
4323  true/false
4324
4325========================================================================== */
4326OMX_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/* ======================================================================
4518FUNCTION
4519  omx_vdec::AllocateOutputBuffer
4520
4521DESCRIPTION
4522  Helper fn for AllocateBuffer in the output pin
4523
4524PARAMETERS
4525  <TBD>.
4526
4527RETURN VALUE
4528  OMX Error None if everything went well.
4529
4530========================================================================== */
4531OMX_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/* ======================================================================
4837FUNCTION
4838  omx_vdec::AllocateBuffer
4839
4840DESCRIPTION
4841  Returns zero if all the buffers released..
4842
4843PARAMETERS
4844  None.
4845
4846RETURN VALUE
4847  true/false
4848
4849========================================================================== */
4850OMX_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/* ======================================================================
4925FUNCTION
4926  omx_vdec::FreeBuffer
4927
4928DESCRIPTION
4929
4930PARAMETERS
4931  None.
4932
4933RETURN VALUE
4934  true/false
4935
4936========================================================================== */
4937OMX_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/* ======================================================================
5084FUNCTION
5085  omx_vdec::EmptyThisBuffer
5086
5087DESCRIPTION
5088  This routine is used to push the encoded video frames to
5089  the video decoder.
5090
5091PARAMETERS
5092  None.
5093
5094RETURN VALUE
5095  OMX Error None if everything went successful.
5096
5097========================================================================== */
5098OMX_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/* ======================================================================
5192FUNCTION
5193  omx_vdec::empty_this_buffer_proxy
5194
5195DESCRIPTION
5196  This routine is used to push the encoded video frames to
5197  the video decoder.
5198
5199PARAMETERS
5200  None.
5201
5202RETURN VALUE
5203  OMX Error None if everything went successful.
5204
5205========================================================================== */
5206OMX_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/* ======================================================================
5434FUNCTION
5435  omx_vdec::FillThisBuffer
5436
5437DESCRIPTION
5438  IL client uses this method to release the frame buffer
5439  after displaying them.
5440
5441PARAMETERS
5442  None.
5443
5444RETURN VALUE
5445  true/false
5446
5447========================================================================== */
5448OMX_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/* ======================================================================
5480FUNCTION
5481  omx_vdec::fill_this_buffer_proxy
5482
5483DESCRIPTION
5484  IL client uses this method to release the frame buffer
5485  after displaying them.
5486
5487PARAMETERS
5488  None.
5489
5490RETURN VALUE
5491  true/false
5492
5493========================================================================== */
5494OMX_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/* ======================================================================
5571FUNCTION
5572  omx_vdec::SetCallbacks
5573
5574DESCRIPTION
5575  Set the callbacks.
5576
5577PARAMETERS
5578  None.
5579
5580RETURN VALUE
5581  OMX Error None if everything successful.
5582
5583========================================================================== */
5584OMX_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/* ======================================================================
5597FUNCTION
5598  omx_vdec::ComponentDeInit
5599
5600DESCRIPTION
5601  Destroys the component and release memory allocated to the heap.
5602
5603PARAMETERS
5604  <TBD>.
5605
5606RETURN VALUE
5607  OMX Error None if everything successful.
5608
5609========================================================================== */
5610OMX_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/* ======================================================================
5712FUNCTION
5713  omx_vdec::UseEGLImage
5714
5715DESCRIPTION
5716  OMX Use EGL Image method implementation <TBD>.
5717
5718PARAMETERS
5719  <TBD>.
5720
5721RETURN VALUE
5722  Not Implemented error.
5723
5724========================================================================== */
5725OMX_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/* ======================================================================
5790FUNCTION
5791  omx_vdec::ComponentRoleEnum
5792
5793DESCRIPTION
5794  OMX Component Role Enum method implementation.
5795
5796PARAMETERS
5797  <TBD>.
5798
5799RETURN VALUE
5800  OMX Error None if everything is successful.
5801========================================================================== */
5802OMX_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/* ======================================================================
5902FUNCTION
5903  omx_vdec::AllocateDone
5904
5905DESCRIPTION
5906  Checks if entire buffer pool is allocated by IL Client or not.
5907  Need this to move to IDLE state.
5908
5909PARAMETERS
5910  None.
5911
5912RETURN VALUE
5913  true/false.
5914
5915========================================================================== */
5916bool 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/* ======================================================================
5933FUNCTION
5934  omx_vdec::AllocateInputDone
5935
5936DESCRIPTION
5937  Checks if I/P buffer pool is allocated by IL Client or not.
5938
5939PARAMETERS
5940  None.
5941
5942RETURN VALUE
5943  true/false.
5944
5945========================================================================== */
5946bool 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/* ======================================================================
5977FUNCTION
5978  omx_vdec::AllocateOutputDone
5979
5980DESCRIPTION
5981  Checks if entire O/P buffer pool is allocated by IL Client or not.
5982
5983PARAMETERS
5984  None.
5985
5986RETURN VALUE
5987  true/false.
5988
5989========================================================================== */
5990bool 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/* ======================================================================
6023FUNCTION
6024  omx_vdec::ReleaseDone
6025
6026DESCRIPTION
6027  Checks if IL client has released all the buffers.
6028
6029PARAMETERS
6030  None.
6031
6032RETURN VALUE
6033  true/false
6034
6035========================================================================== */
6036bool 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/* ======================================================================
6052FUNCTION
6053  omx_vdec::ReleaseOutputDone
6054
6055DESCRIPTION
6056  Checks if IL client has released all the buffers.
6057
6058PARAMETERS
6059  None.
6060
6061RETURN VALUE
6062  true/false
6063
6064========================================================================== */
6065bool 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/* ======================================================================
6094FUNCTION
6095  omx_vdec::ReleaseInputDone
6096
6097DESCRIPTION
6098  Checks if IL client has released all the buffers.
6099
6100PARAMETERS
6101  None.
6102
6103RETURN VALUE
6104  true/false
6105
6106========================================================================== */
6107bool 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
6134OMX_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
6268OMX_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
6314int 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
6499OMX_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
6545OMX_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
6611OMX_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
6734OMX_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
6992OMX_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
7063int 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_mask = ION_HEAP(MEM_HEAP_ID);
7094    alloc_data->flags |= ION_SECURE;
7095  } else {
7096    alloc_data->heap_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
7122void 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
7138bool 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
7157void 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
7194void 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}
7240void 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
7254OMX_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
7354OMX_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){
7377fmt.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
7391OMX_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
7407OMX_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
7421OMX_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
7499OMX_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
7641void 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
7712void 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
7744void 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
7774void 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
7909OMX_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
7979OMX_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
7999void 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
8074void 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
8105void 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
8148void 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
8165void 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
8176OMX_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
8206void 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
8216void 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
8245OMX_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
8340OMX_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