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