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