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