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