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