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