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