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