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