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