1 /*---------------------------------------------------------------------------------------
2 Copyright (c) 2013-2015, The Linux Foundation. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions 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 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED 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
68 int inputBufferFile;
69 char inputfilename[] = "/sdcard/input-bitstream";
70 #endif
71 #ifdef OUTPUT_BUFFER_LOG
72 int outputBufferFile;
73 char outputfilename[] = "/sdcard/output.yuv";
74 #endif
75 #ifdef OUTPUT_EXTRADATA_LOG
76 FILE *outputExtradataFile;
77 char 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
async_message_thread(void * input)107 void* 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
async_message_thread(void * input)289 void* 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 
message_thread(void * input)374 void* 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 
post_message(omx_vdpp * omx,unsigned char id)406 void 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
~omx_cmd_queue()415 omx_vdpp::omx_cmd_queue::~omx_cmd_queue()
416 {
417   // Nothing to do
418 }
419 
420 // omx cmd queue constructor
omx_cmd_queue()421 omx_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
insert_entry(unsigned p1,unsigned p2,unsigned id)427 bool 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
pop_entry(unsigned * p1,unsigned * p2,unsigned * id)451 bool 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
get_q_msg_type()475 unsigned omx_vdpp::omx_cmd_queue::get_q_msg_type()
476 {
477     return m_q[m_read].id;
478 }
479 
480 #ifdef _ANDROID_
ts_arr_list()481 omx_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 }
~ts_arr_list()486 omx_vdpp::ts_arr_list::~ts_arr_list()
487 {
488   //free m_ts_arr_list?
489 }
490 
insert_ts(OMX_TICKS ts)491 bool 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 
pop_min_ts(OMX_TICKS & ts)519 bool 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 
reset_ts_list()567 bool 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
get_omx_component_factory_fn(void)582 void *get_omx_component_factory_fn(void)
583 {
584   return (new omx_vdpp);
585 }
586 
587 /* ======================================================================
588 FUNCTION
589   omx_vdpp::omx_vdpp
590 
591 DESCRIPTION
592   Constructor
593 
594 PARAMETERS
595   None
596 
597 RETURN VALUE
598   None.
599 ========================================================================== */
omx_vdpp()600 omx_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 
subscribe_to_events(int fd)679 static 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 
unsubscribe_to_events(int fd)703 static 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 /* ======================================================================
727 FUNCTION
728   omx_vdpp::~omx_vdpp
729 
730 DESCRIPTION
731   Destructor
732 
733 PARAMETERS
734   None
735 
736 RETURN VALUE
737   None.
738 ========================================================================== */
~omx_vdpp()739 omx_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 
release_buffers(omx_vdpp * obj,enum vdpp_buffer buffer_type)781 int 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 /* ======================================================================
801 FUNCTION
802   omx_vdpp::process_event_cb
803 
804 DESCRIPTION
805   IL Client callbacks are generated through this routine. The VDPP
806   provides the thread context for this routine.
807 
808 PARAMETERS
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 
815 RETURN VALUE
816   None.
817 
818 ========================================================================== */
process_event_cb(void * ctxt,unsigned char id)819 void 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 
update_resolution(uint32_t width,uint32_t height,uint32_t stride,uint32_t scan_lines)1405 int 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 /* ======================================================================
1427 FUNCTION
1428   omx_vdpp::ComponentInit
1429 
1430 DESCRIPTION
1431   Initialize the component.
1432 
1433 PARAMETERS
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 
1440 RETURN VALUE
1441   None.
1442 
1443 ========================================================================== */
component_init(OMX_STRING role)1444 OMX_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 /* ======================================================================
1759 FUNCTION
1760   omx_vdpp::GetComponentVersion
1761 
1762 DESCRIPTION
1763   Returns the component version.
1764 
1765 PARAMETERS
1766   TBD.
1767 
1768 RETURN VALUE
1769   OMX_ErrorNone.
1770 
1771 ========================================================================== */
get_component_version(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STRING componentName,OMX_OUT OMX_VERSIONTYPE * componentVersion,OMX_OUT OMX_VERSIONTYPE * specVersion,OMX_OUT OMX_UUIDTYPE * componentUUID)1772 OMX_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 /* ======================================================================
1794 FUNCTION
1795   omx_vdpp::SendCommand
1796 
1797 DESCRIPTION
1798   Returns zero if all the buffers released..
1799 
1800 PARAMETERS
1801   None.
1802 
1803 RETURN VALUE
1804   true/false
1805 
1806 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)1807 OMX_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 /* ======================================================================
1833 FUNCTION
1834   omx_vdpp::SendCommand
1835 
1836 DESCRIPTION
1837   Returns zero if all the buffers released..
1838 
1839 PARAMETERS
1840   None.
1841 
1842 RETURN VALUE
1843   true/false
1844 
1845 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)1846 OMX_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 Invalid to any state */
2200     if(eState == OMX_StateLoaded || eState == OMX_StateWaitForResources ||
2201        eState == OMX_StateIdle || eState == OMX_StateExecuting ||
2202        eState == OMX_StatePause || eState == 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 /* ======================================================================
2375 FUNCTION
2376   omx_vdpp::ExecuteOmxFlush
2377 
2378 DESCRIPTION
2379   Executes the OMX flush.
2380 
2381 PARAMETERS
2382   flushtype - input flush(1)/output flush(0)/ both.
2383 
2384 RETURN VALUE
2385   true/false
2386 
2387 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)2388 bool 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 /*=========================================================================
2479 FUNCTION : execute_output_flush
2480 
2481 DESCRIPTION
2482   Executes the OMX flush at OUTPUT PORT.
2483 
2484 PARAMETERS
2485   None.
2486 
2487 RETURN VALUE
2488   true/false
2489 ==========================================================================*/
execute_output_flush()2490 bool 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 /*=========================================================================
2523 FUNCTION : execute_input_flush
2524 
2525 DESCRIPTION
2526   Executes the OMX flush at INPUT PORT.
2527 
2528 PARAMETERS
2529   None.
2530 
2531 RETURN VALUE
2532   true/false
2533 ==========================================================================*/
execute_input_flush()2534 bool 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 /* ======================================================================
2592 FUNCTION
2593   omx_vdpp::SendCommandEvent
2594 
2595 DESCRIPTION
2596   Send the event to VDPP pipe.  This is needed to generate the callbacks
2597   in VDPP thread context.
2598 
2599 PARAMETERS
2600   None.
2601 
2602 RETURN VALUE
2603   true/false
2604 
2605 ========================================================================== */
post_event(unsigned int p1,unsigned int p2,unsigned int id)2606 bool 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 /* ======================================================================
2641 FUNCTION
2642   omx_vdpp::GetParameter
2643 
2644 DESCRIPTION
2645   OMX Get Parameter method implementation
2646 
2647 PARAMETERS
2648   <TBD>.
2649 
2650 RETURN VALUE
2651   Error None if successful.
2652 
2653 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)2654 OMX_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_)
use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_PTR data)2877 OMX_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 /* ======================================================================
2908 FUNCTION
2909   omx_vdpp::Setparameter
2910 
2911 DESCRIPTION
2912   OMX Set Parameter method implementation.
2913 
2914 PARAMETERS
2915   <TBD>.
2916 
2917 RETURN VALUE
2918   OMX Error None if successful.
2919 
2920 ========================================================================== */
set_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_IN OMX_PTR paramData)2921 OMX_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 /* ======================================================================
3426 FUNCTION
3427   omx_vdpp::GetConfig
3428 
3429 DESCRIPTION
3430   OMX Get Config Method implementation.
3431 
3432 PARAMETERS
3433   <TBD>.
3434 
3435 RETURN VALUE
3436   OMX Error None if successful.
3437 
3438 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)3439 OMX_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 /* ======================================================================
3476 FUNCTION
3477   omx_vdpp::SetConfig
3478 
3479 DESCRIPTION
3480   OMX Set Config method implementation
3481 
3482 PARAMETERS
3483   <TBD>.
3484 
3485 RETURN VALUE
3486   OMX Error None if successful.
3487 ========================================================================== */
set_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_IN OMX_PTR configData)3488 OMX_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 /* ======================================================================
3736 FUNCTION
3737   omx_vdpp::GetExtensionIndex
3738 
3739 DESCRIPTION
3740   OMX GetExtensionIndex method implementaion.  <TBD>
3741 
3742 PARAMETERS
3743   <TBD>.
3744 
3745 RETURN VALUE
3746   OMX Error None if everything successful.
3747 
3748 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)3749 OMX_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 /* ======================================================================
3825 FUNCTION
3826   omx_vdpp::GetState
3827 
3828 DESCRIPTION
3829   Returns the state information back to the caller.<TBD>
3830 
3831 PARAMETERS
3832   <TBD>.
3833 
3834 RETURN VALUE
3835   Error None if everything is successful.
3836 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)3837 OMX_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 /* ======================================================================
3846 FUNCTION
3847   omx_vdpp::ComponentTunnelRequest
3848 
3849 DESCRIPTION
3850   OMX Component Tunnel Request method implementation. <TBD>
3851 
3852 PARAMETERS
3853   None.
3854 
3855 RETURN VALUE
3856   OMX Error None if everything successful.
3857 
3858 ========================================================================== */
component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_HANDLETYPE peerComponent,OMX_IN OMX_U32 peerPort,OMX_INOUT OMX_TUNNELSETUPTYPE * tunnelSetup)3859 OMX_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 
use_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)3869 OMX_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 /* ======================================================================
4070 FUNCTION
4071   omx_vdpp::use_input_heap_buffers
4072 
4073 DESCRIPTION
4074   OMX Use Buffer Heap allocation method implementation.
4075 
4076 PARAMETERS
4077   <TBD>.
4078 
4079 RETURN VALUE
4080   OMX Error None , if everything successful.
4081 
4082 ========================================================================== */
use_input_heap_buffers(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)4083 OMX_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 /* ======================================================================
4203 FUNCTION
4204   omx_vdpp::use_input_buffers
4205 
4206 DESCRIPTION
4207   OMX Use Buffer method implementation.
4208 
4209 PARAMETERS
4210   <TBD>.
4211 
4212 RETURN VALUE
4213   OMX Error None , if everything successful.
4214 
4215 ========================================================================== */
use_input_buffers(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)4216 OMX_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 /* ======================================================================
4407 FUNCTION
4408   omx_vdpp::UseBuffer
4409 
4410 DESCRIPTION
4411   OMX Use Buffer method implementation.
4412 
4413 PARAMETERS
4414   <TBD>.
4415 
4416 RETURN VALUE
4417   OMX Error None , if everything successful.
4418 
4419 ========================================================================== */
use_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes,OMX_IN OMX_U8 * buffer)4420 OMX_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 
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)4483 OMX_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 
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)4531 OMX_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 
allocate_input_heap_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)4598 OMX_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 /* ======================================================================
4681 FUNCTION
4682   omx_vdpp::AllocateInputBuffer
4683 
4684 DESCRIPTION
4685   Helper function for allocate buffer in the input pin
4686 
4687 PARAMETERS
4688   None.
4689 
4690 RETURN VALUE
4691   true/false
4692 
4693 ========================================================================== */
allocate_input_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)4694 OMX_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 /* ======================================================================
4831 FUNCTION
4832   omx_vdpp::AllocateOutputBuffer
4833 
4834 DESCRIPTION
4835   Helper fn for AllocateBuffer in the output pin
4836 
4837 PARAMETERS
4838   <TBD>.
4839 
4840 RETURN VALUE
4841   OMX Error None if everything went well.
4842 
4843 ========================================================================== */
allocate_output_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)4844 OMX_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 /* ======================================================================
5050 FUNCTION
5051   omx_vdpp::AllocateBuffer
5052 
5053 DESCRIPTION
5054   Returns zero if all the buffers released..
5055 
5056 PARAMETERS
5057   None.
5058 
5059 RETURN VALUE
5060   true/false
5061 
5062 ========================================================================== */
allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN OMX_U32 bytes)5063 OMX_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 /* ======================================================================
5131 FUNCTION
5132   omx_vdpp::FreeBuffer
5133 
5134 DESCRIPTION
5135 
5136 PARAMETERS
5137   None.
5138 
5139 RETURN VALUE
5140   true/false
5141 
5142 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5143 OMX_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 /* ======================================================================
5289 FUNCTION
5290   omx_vdpp::EmptyThisBuffer
5291 
5292 DESCRIPTION
5293   This routine is used to push the video frames to VDPP.
5294 
5295 PARAMETERS
5296   None.
5297 
5298 RETURN VALUE
5299   OMX Error None if everything went successful.
5300 
5301 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5302 OMX_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 /* ======================================================================
5364 FUNCTION
5365   omx_vdpp::empty_this_buffer_proxy
5366 
5367 DESCRIPTION
5368   This routine is used to push the video decoder output frames to
5369   the VDPP.
5370 
5371 PARAMETERS
5372   None.
5373 
5374 RETURN VALUE
5375   OMX Error None if everything went successful.
5376 
5377 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5378 OMX_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 /* ======================================================================
5669 FUNCTION
5670   omx_vdpp::FillThisBuffer
5671 
5672 DESCRIPTION
5673   IL client uses this method to release the frame buffer
5674   after displaying them.
5675 
5676 PARAMETERS
5677   None.
5678 
5679 RETURN VALUE
5680   true/false
5681 
5682 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5683 OMX_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 /* ======================================================================
5716 FUNCTION
5717   omx_vdpp::fill_this_buffer_proxy
5718 
5719 DESCRIPTION
5720   IL client uses this method to release the frame buffer
5721   after displaying them.
5722 
5723 PARAMETERS
5724   None.
5725 
5726 RETURN VALUE
5727   true/false
5728 
5729 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)5730 OMX_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 /* ======================================================================
5849 FUNCTION
5850   omx_vdpp::SetCallbacks
5851 
5852 DESCRIPTION
5853   Set the callbacks.
5854 
5855 PARAMETERS
5856   None.
5857 
5858 RETURN VALUE
5859   OMX Error None if everything successful.
5860 
5861 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)5862 OMX_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 /* ======================================================================
5875 FUNCTION
5876   omx_vdpp::ComponentDeInit
5877 
5878 DESCRIPTION
5879   Destroys the component and release memory allocated to the heap.
5880 
5881 PARAMETERS
5882   <TBD>.
5883 
5884 RETURN VALUE
5885   OMX Error None if everything successful.
5886 
5887 ========================================================================== */
component_deinit(OMX_IN OMX_HANDLETYPE hComp)5888 OMX_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 /* ======================================================================
5963 FUNCTION
5964   omx_vdpp::UseEGLImage
5965 
5966 DESCRIPTION
5967   OMX Use EGL Image method implementation <TBD>.
5968 
5969 PARAMETERS
5970   <TBD>.
5971 
5972 RETURN VALUE
5973   Not Implemented error.
5974 
5975 ========================================================================== */
use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,OMX_INOUT OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_IN OMX_U32 port,OMX_IN OMX_PTR appData,OMX_IN void * eglImage)5976 OMX_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 /* ======================================================================
5985 FUNCTION
5986   omx_vdpp::ComponentRoleEnum
5987 
5988 DESCRIPTION
5989   OMX Component Role Enum method implementation.
5990 
5991 PARAMETERS
5992   <TBD>.
5993 
5994 RETURN VALUE
5995   OMX Error None if everything is successful.
5996 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)5997 OMX_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 /* ======================================================================
6025 FUNCTION
6026   omx_vdpp::AllocateDone
6027 
6028 DESCRIPTION
6029   Checks if entire buffer pool is allocated by IL Client or not.
6030   Need this to move to IDLE state.
6031 
6032 PARAMETERS
6033   None.
6034 
6035 RETURN VALUE
6036   true/false.
6037 
6038 ========================================================================== */
allocate_done(void)6039 bool 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 /* ======================================================================
6058 FUNCTION
6059   omx_vdpp::AllocateInputDone
6060 
6061 DESCRIPTION
6062   Checks if I/P buffer pool is allocated by IL Client or not.
6063 
6064 PARAMETERS
6065   None.
6066 
6067 RETURN VALUE
6068   true/false.
6069 
6070 ========================================================================== */
allocate_input_done(void)6071 bool 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 /* ======================================================================
6106 FUNCTION
6107   omx_vdpp::AllocateOutputDone
6108 
6109 DESCRIPTION
6110   Checks if entire O/P buffer pool is allocated by IL Client or not.
6111 
6112 PARAMETERS
6113   None.
6114 
6115 RETURN VALUE
6116   true/false.
6117 
6118 ========================================================================== */
allocate_output_done(void)6119 bool 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 /* ======================================================================
6152 FUNCTION
6153   omx_vdpp::ReleaseDone
6154 
6155 DESCRIPTION
6156   Checks if IL client has released all the buffers.
6157 
6158 PARAMETERS
6159   None.
6160 
6161 RETURN VALUE
6162   true/false
6163 
6164 ========================================================================== */
release_done(void)6165 bool 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 /* ======================================================================
6181 FUNCTION
6182   omx_vdpp::ReleaseOutputDone
6183 
6184 DESCRIPTION
6185   Checks if IL client has released all the buffers.
6186 
6187 PARAMETERS
6188   None.
6189 
6190 RETURN VALUE
6191   true/false
6192 
6193 ========================================================================== */
release_output_done(void)6194 bool 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 /* ======================================================================
6223 FUNCTION
6224   omx_vdpp::ReleaseInputDone
6225 
6226 DESCRIPTION
6227   Checks if IL client has released all the buffers.
6228 
6229 PARAMETERS
6230   None.
6231 
6232 RETURN VALUE
6233   true/false
6234 
6235 ========================================================================== */
release_input_done(void)6236 bool 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 
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)6263 OMX_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 
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)6369 OMX_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 
async_message_process(void * context,void * message)6395 int 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
align_pmem_buffers(int pmem_fd,OMX_U32 buffer_size,OMX_U32 alignment)6553 bool 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
alloc_map_ion_memory(OMX_U32 buffer_size,OMX_U32 alignment,struct ion_allocation_data * alloc_data,struct ion_fd_data * fd_data,int flag)6573 int 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 
free_ion_memory(struct vdpp_ion * buf_ion_info)6623 void 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
free_output_buffer_header()6639 void 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 
free_input_buffer_header()6676 void 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 
stream_off(OMX_U32 port)6716 int 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
get_buffer_req(vdpp_allocatorproperty * buffer_prop)6761 OMX_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
set_buffer_req(vdpp_allocatorproperty * buffer_prop)6816 OMX_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
get_buffer_req(vdpp_allocatorproperty * buffer_prop)6839 OMX_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
set_buffer_req(vdpp_allocatorproperty * buffer_prop)7007 OMX_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 
update_portdef(OMX_PARAM_PORTDEFINITIONTYPE * portDefn)7109 OMX_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 
allocate_output_headers()7177 OMX_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 
complete_pending_buffer_done_cbs()7283 void 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 
set_frame_rate(OMX_S64 act_timestamp)7354 void 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 
adjust_timestamp(OMX_S64 & act_timestamp)7400 void 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 
enable_extradata(OMX_U32 requested_extradata,bool enable)7430 OMX_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 
setFormatParams(int pixelFormat,double bytesperpixel[],unsigned char * planesCount)7449 void 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 
openInput(const char * inputName)7535 int 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