• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2012, Code Aurora Forum. All rights reserved.
3 
4 Redistribution and use in source and binary forms, with or without
5 modification, are permitted provided that the following conditions are met:
6     * Redistributions of source code must retain the above copyright
7       notice, this list of conditions and the following disclaimer.
8     * Redistributions in binary form must reproduce the above copyright
9       notice, this list of conditions and the following disclaimer in the
10       documentation and/or other materials provided with the distribution.
11     * Neither the name of Code Aurora nor
12       the names of its contributors may be used to endorse or promote
13       products derived from this software without specific prior written
14       permission.
15 
16 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18 IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19 NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
20 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
23 OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
24 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
25 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
26 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 --------------------------------------------------------------------------*/
28 /*============================================================================
29                             O p e n M A X   w r a p p e r s
30                              O p e n  M A X   C o r e
31 
32 *//** @file omx_video_base.cpp
33   This module contains the implementation of the OpenMAX core & component.
34 
35 *//*========================================================================*/
36 
37 //////////////////////////////////////////////////////////////////////////////
38 //                             Include Files
39 //////////////////////////////////////////////////////////////////////////////
40 
41 #include <string.h>
42 #include "omx_video_base.h"
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <sys/prctl.h>
48 #ifdef _ANDROID_ICS_
49 #include <media/hardware/HardwareAPI.h>
50 #include <gralloc_priv.h>
51 #endif
52 #ifndef _ANDROID_
53 #include <glib.h>
54 #define strlcpy g_strlcpy
55 #endif
56 #define H264_SUPPORTED_WIDTH (480)
57 #define H264_SUPPORTED_HEIGHT (368)
58 
59 #define MPEG4_SUPPORTED_WIDTH (480)
60 #define MPEG4_SUPPORTED_HEIGHT (368)
61 
62 #define VC1_SP_MP_START_CODE        0xC5000000
63 #define VC1_SP_MP_START_CODE_MASK   0xFF000000
64 #define VC1_AP_START_CODE           0x00000100
65 #define VC1_AP_START_CODE_MASK      0xFFFFFF00
66 #define VC1_STRUCT_C_PROFILE_MASK   0xF0
67 #define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
68 #define VC1_SIMPLE_PROFILE          0
69 #define VC1_MAIN_PROFILE            1
70 #define VC1_ADVANCE_PROFILE         3
71 #define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
72 #define VC1_SIMPLE_PROFILE_MED_LEVEL  2
73 #define VC1_STRUCT_C_LEN            4
74 #define VC1_STRUCT_C_POS            8
75 #define VC1_STRUCT_A_POS            12
76 #define VC1_STRUCT_B_POS            24
77 #define VC1_SEQ_LAYER_SIZE          36
78 
79 #define IS_NOT_ALIGNED( num, to) (num & (to-1))
80 #define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
81 #define SZ_2K (2048)
82 
83 typedef struct OMXComponentCapabilityFlagsType
84 {
85     ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
86     OMX_BOOL iIsOMXComponentMultiThreaded;
87     OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
88     OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
89     OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
90     OMX_BOOL iOMXComponentSupportsPartialFrames;
91     OMX_BOOL iOMXComponentUsesNALStartCodes;
92     OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
93     OMX_BOOL iOMXComponentUsesFullAVCFrames;
94 
95 } OMXComponentCapabilityFlagsType;
96 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
97 #ifdef OUTPUT_BUFFER_LOG
98 extern FILE *outputBufferFile1;
99 #endif
100 
message_thread(void * input)101 void* message_thread(void *input)
102 {
103   omx_video* omx = reinterpret_cast<omx_video*>(input);
104   unsigned char id;
105   int n;
106 
107   DEBUG_PRINT_LOW("omx_venc: message thread start\n");
108   prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
109   while(1)
110   {
111     n = read(omx->m_pipe_in, &id, 1);
112     if(0 == n)
113     {
114       break;
115     }
116 
117     if(1 == n)
118     {
119       omx->process_event_cb(omx, id);
120     }
121 #ifdef QLE_BUILD
122     if(n < 0) break;
123 #else
124     if((n < 0) && (errno != EINTR)) break;
125 #endif
126   }
127   DEBUG_PRINT_LOW("omx_venc: message thread stop\n");
128   return 0;
129 }
130 
post_message(omx_video * omx,unsigned char id)131 void post_message(omx_video *omx, unsigned char id)
132 {
133   DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id);
134   write(omx->m_pipe_out, &id, 1);
135 }
136 
137 // omx_cmd_queue destructor
~omx_cmd_queue()138 omx_video::omx_cmd_queue::~omx_cmd_queue()
139 {
140   // Nothing to do
141 }
142 
143 // omx cmd queue constructor
omx_cmd_queue()144 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
145 {
146   memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
147 }
148 
149 // omx cmd queue insert
insert_entry(unsigned p1,unsigned p2,unsigned id)150 bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
151 {
152   bool ret = true;
153   if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
154   {
155     m_q[m_write].id       = id;
156     m_q[m_write].param1   = p1;
157     m_q[m_write].param2   = p2;
158     m_write++;
159     m_size ++;
160     if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
161     {
162       m_write = 0;
163     }
164   }
165   else
166   {
167     ret = false;
168     DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n");
169   }
170   return ret;
171 }
172 
173 // omx cmd queue pop
pop_entry(unsigned * p1,unsigned * p2,unsigned * id)174 bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
175 {
176   bool ret = true;
177   if(m_size > 0)
178   {
179     *id = m_q[m_read].id;
180     *p1 = m_q[m_read].param1;
181     *p2 = m_q[m_read].param2;
182     // Move the read pointer ahead
183     ++m_read;
184     --m_size;
185     if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
186     {
187       m_read = 0;
188     }
189   }
190   else
191   {
192     ret = false;
193   }
194   return ret;
195 }
196 
197 // Retrieve the first mesg type in the queue
get_q_msg_type()198 unsigned omx_video::omx_cmd_queue::get_q_msg_type()
199 {
200   return m_q[m_read].id;
201 }
202 
203 
204 
205 #ifdef _ANDROID_
VideoHeap(int fd,size_t size,void * base)206 VideoHeap::VideoHeap(int fd, size_t size, void* base)
207 {
208   // dup file descriptor, map once, use pmem
209   init(dup(fd), base, size, 0 , MEM_DEVICE);
210 }
211 #endif // _ANDROID_
212 
213 /* ======================================================================
214 FUNCTION
215   omx_venc::omx_venc
216 
217 DESCRIPTION
218   Constructor
219 
220 PARAMETERS
221   None
222 
223 RETURN VALUE
224   None.
225 ========================================================================== */
omx_video()226 omx_video::omx_video(): m_state(OMX_StateInvalid),
227                         m_app_data(NULL),
228                         m_inp_mem_ptr(NULL),
229                         m_out_mem_ptr(NULL),
230                         m_pInput_pmem(NULL),
231                         m_pOutput_pmem(NULL),
232 #ifdef USE_ION
233                         m_pInput_ion(NULL),
234                         m_pOutput_ion(NULL),
235 #endif
236                         pending_input_buffers(0),
237                         pending_output_buffers(0),
238                         m_out_bm_count(0),
239                         m_inp_bm_count(0),
240                         m_flags(0),
241                         m_event_port_settings_sent(false),
242                         output_flush_progress (false),
243                         input_flush_progress (false),
244                         input_use_buffer (false),
245                         output_use_buffer (false),
246                         m_use_input_pmem(OMX_FALSE),
247                         m_use_output_pmem(OMX_FALSE),
248                         m_etb_count(0),
249                         m_fbd_count(0),
250                         m_error_propogated(false),
251                         m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
252                         psource_frame(NULL),
253                         pdest_frame(NULL),
254                         c2d_opened(false),
255                         secure_session(false)
256 {
257   DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
258   memset(&m_cmp,0,sizeof(m_cmp));
259   memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
260   secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar;
261   pthread_mutex_init(&m_lock, NULL);
262   sem_init(&m_cmd_lock,0,0);
263 }
264 
265 
266 /* ======================================================================
267 FUNCTION
268   omx_venc::~omx_venc
269 
270 DESCRIPTION
271   Destructor
272 
273 PARAMETERS
274   None
275 
276 RETURN VALUE
277   None.
278 ========================================================================== */
~omx_video()279 omx_video::~omx_video()
280 {
281   DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
282   if(m_pipe_in) close(m_pipe_in);
283   if(m_pipe_out) close(m_pipe_out);
284   DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
285   pthread_join(msg_thread_id,NULL);
286   DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
287   pthread_join(async_thread_id,NULL);
288   pthread_mutex_destroy(&m_lock);
289   sem_destroy(&m_cmd_lock);
290   DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
291       m_fbd_count);
292   DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
293   DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
294 }
295 
296 /* ======================================================================
297 FUNCTION
298   omx_venc::OMXCntrlProcessMsgCb
299 
300 DESCRIPTION
301   IL Client callbacks are generated through this routine. The decoder
302   provides the thread context for this routine.
303 
304 PARAMETERS
305   ctxt -- Context information related to the self.
306   id   -- Event identifier. This could be any of the following:
307           1. Command completion event
308           2. Buffer done callback event
309           3. Frame done callback event
310 
311 RETURN VALUE
312   None.
313 
314 ========================================================================== */
process_event_cb(void * ctxt,unsigned char id)315 void omx_video::process_event_cb(void *ctxt, unsigned char id)
316 {
317   unsigned p1; // Parameter - 1
318   unsigned p2; // Parameter - 2
319   unsigned ident;
320   unsigned qsize=0; // qsize
321   omx_video *pThis = (omx_video *) ctxt;
322 
323   if(!pThis)
324   {
325     DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
326     return;
327   }
328 
329   // Protect the shared queue data structure
330   do
331   {
332     /*Read the message id's from the queue*/
333 
334     pthread_mutex_lock(&pThis->m_lock);
335     qsize = pThis->m_cmd_q.m_size;
336     if(qsize)
337     {
338       pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
339     }
340 
341     if(qsize == 0)
342     {
343       qsize = pThis->m_ftb_q.m_size;
344       if(qsize)
345       {
346         pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
347       }
348     }
349 
350     if(qsize == 0)
351     {
352       qsize = pThis->m_etb_q.m_size;
353       if(qsize)
354       {
355         pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
356       }
357     }
358 
359     pthread_mutex_unlock(&pThis->m_lock);
360 
361     /*process message if we have one*/
362     if(qsize > 0)
363     {
364       id = ident;
365       switch(id)
366       {
367       case OMX_COMPONENT_GENERATE_EVENT:
368         if(pThis->m_pCallbacks.EventHandler)
369         {
370           switch(p1)
371           {
372           case OMX_CommandStateSet:
373             pThis->m_state = (OMX_STATETYPE) p2;
374             DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
375             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
376                                              OMX_EventCmdComplete, p1, p2, NULL);
377             break;
378 
379           case OMX_EventError:
380             DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
381             if(p2 == OMX_ErrorHardware)
382             {
383               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
384                                                OMX_EventError,OMX_ErrorHardware,0,NULL);
385             }
386             else
387             {
388               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
389                                                OMX_EventError, p2, NULL, NULL );
390 
391             }
392             break;
393 
394           case OMX_CommandPortDisable:
395             DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
396                         "state \n", p2);
397             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
398                                              OMX_EventCmdComplete, p1, p2, NULL );
399             break;
400           case OMX_CommandPortEnable:
401             DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
402                         , p2);
403             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
404                                              OMX_EventCmdComplete, p1, p2, NULL );
405             break;
406 
407           default:
408             DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1);
409             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
410                                              OMX_EventCmdComplete, p1, p2, NULL );
411             break;
412 
413           }
414         }
415         else
416         {
417           DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
418         }
419         break;
420       case OMX_COMPONENT_GENERATE_ETB_OPQ:
421         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n");
422         if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
423                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
424         {
425           DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
426           pThis->omx_report_error ();
427         }
428         break;
429       case OMX_COMPONENT_GENERATE_ETB:
430         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n");
431         if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
432                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
433         {
434           DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
435           pThis->omx_report_error ();
436         }
437         break;
438 
439       case OMX_COMPONENT_GENERATE_FTB:
440         if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
441                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
442         {
443           DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
444           pThis->omx_report_error ();
445         }
446         break;
447 
448       case OMX_COMPONENT_GENERATE_COMMAND:
449         pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
450                                   (OMX_U32)p2,(OMX_PTR)NULL);
451         break;
452 
453       case OMX_COMPONENT_GENERATE_EBD:
454         if( pThis->empty_buffer_done(&pThis->m_cmp,
455                                      (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
456         {
457           DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
458           pThis->omx_report_error ();
459         }
460         break;
461 
462       case OMX_COMPONENT_GENERATE_FBD:
463         if( pThis->fill_buffer_done(&pThis->m_cmp,
464                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
465         {
466           DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
467           pThis->omx_report_error ();
468         }
469         break;
470 
471       case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
472 
473         pThis->input_flush_progress = false;
474         DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
475         m_etb_count = 0;
476         if(pThis->m_pCallbacks.EventHandler)
477         {
478           /*Check if we need generate event for Flush done*/
479           if(BITMASK_PRESENT(&pThis->m_flags,
480                              OMX_COMPONENT_INPUT_FLUSH_PENDING))
481           {
482             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
483             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
484                                              OMX_EventCmdComplete,OMX_CommandFlush,
485                                              PORT_INDEX_IN,NULL );
486           }
487           else if(BITMASK_PRESENT(&pThis->m_flags,
488                                   OMX_COMPONENT_IDLE_PENDING))
489           {
490             if(!pThis->output_flush_progress)
491             {
492               DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n");
493               if(dev_stop() != 0)
494               {
495                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
496                 pThis->omx_report_error ();
497               }
498             }
499           }
500         }
501 
502         break;
503 
504       case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
505 
506         pThis->output_flush_progress = false;
507         DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
508         m_fbd_count = 0;
509         if(pThis->m_pCallbacks.EventHandler)
510         {
511           /*Check if we need generate event for Flush done*/
512           if(BITMASK_PRESENT(&pThis->m_flags,
513                              OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
514           {
515             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
516 
517             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
518                                              OMX_EventCmdComplete,OMX_CommandFlush,
519                                              PORT_INDEX_OUT,NULL );
520           }
521           else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
522           {
523             DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n");
524             if(!pThis->input_flush_progress)
525             {
526               if(dev_stop() != 0)
527               {
528                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
529                 pThis->omx_report_error ();
530               }
531             }
532           }
533         }
534         break;
535 
536       case OMX_COMPONENT_GENERATE_START_DONE:
537         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
538 
539         if(pThis->m_pCallbacks.EventHandler)
540         {
541           DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
542           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
543           {
544             DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
545                              executing");
546             // Send the callback now
547             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
548             pThis->m_state = OMX_StateExecuting;
549             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
550                                              OMX_EventCmdComplete,OMX_CommandStateSet,
551                                              OMX_StateExecuting, NULL);
552           }
553           else if(BITMASK_PRESENT(&pThis->m_flags,
554                                   OMX_COMPONENT_PAUSE_PENDING))
555           {
556             if(dev_pause())
557             {
558               DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
559               pThis->omx_report_error ();
560             }
561           }
562           else if (BITMASK_PRESENT(&pThis->m_flags,
563                                    OMX_COMPONENT_LOADED_START_PENDING))
564           {
565             if(dev_loaded_start_done())
566             {
567               DEBUG_PRINT_LOW("successful loaded Start Done!");
568             }
569             else
570             {
571               DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
572               pThis->omx_report_error ();
573             }
574             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
575           }
576           else
577           {
578             DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
579           }
580         }
581         else
582         {
583           DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
584         }
585         break;
586 
587       case OMX_COMPONENT_GENERATE_PAUSE_DONE:
588         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
589         if(pThis->m_pCallbacks.EventHandler)
590         {
591           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
592           {
593             //Send the callback now
594             pThis->complete_pending_buffer_done_cbs();
595             DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n");
596             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
597             pThis->m_state = OMX_StatePause;
598             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
599                                              OMX_EventCmdComplete,OMX_CommandStateSet,
600                                              OMX_StatePause, NULL);
601           }
602         }
603 
604         break;
605 
606       case OMX_COMPONENT_GENERATE_RESUME_DONE:
607         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
608         if(pThis->m_pCallbacks.EventHandler)
609         {
610           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
611           {
612             // Send the callback now
613             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
614             pThis->m_state = OMX_StateExecuting;
615             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
616                                              OMX_EventCmdComplete,OMX_CommandStateSet,
617                                              OMX_StateExecuting,NULL);
618           }
619         }
620 
621         break;
622 
623       case OMX_COMPONENT_GENERATE_STOP_DONE:
624         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
625         if(pThis->m_pCallbacks.EventHandler)
626         {
627           pThis->complete_pending_buffer_done_cbs();
628           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
629           {
630             // Send the callback now
631             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
632             pThis->m_state = OMX_StateIdle;
633             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
634                                              OMX_EventCmdComplete,OMX_CommandStateSet,
635                                              OMX_StateIdle,NULL);
636           }
637           else if (BITMASK_PRESENT(&pThis->m_flags,
638                                    OMX_COMPONENT_LOADED_STOP_PENDING))
639           {
640             if(dev_loaded_stop_done())
641             {
642               DEBUG_PRINT_LOW("successful loaded Stop Done!");
643             }
644             else
645             {
646               DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
647               pThis->omx_report_error ();
648             }
649             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
650           }
651           else
652           {
653             DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
654           }
655         }
656 
657         break;
658 
659       case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
660         DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
661         pThis->omx_report_error ();
662         break;
663 
664       default:
665         DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id);
666         break;
667       }
668     }
669 
670     pthread_mutex_lock(&pThis->m_lock);
671     qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
672             pThis->m_etb_q.m_size;
673 
674     pthread_mutex_unlock(&pThis->m_lock);
675 
676   }
677   while(qsize>0);
678   DEBUG_PRINT_LOW("\n exited the while loop\n");
679 
680 }
681 
682 
683 
684 
685 /* ======================================================================
686 FUNCTION
687   omx_venc::GetComponentVersion
688 
689 DESCRIPTION
690   Returns the component version.
691 
692 PARAMETERS
693   TBD.
694 
695 RETURN VALUE
696   OMX_ErrorNone.
697 
698 ========================================================================== */
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)699 OMX_ERRORTYPE  omx_video::get_component_version
700 (
701 OMX_IN OMX_HANDLETYPE hComp,
702 OMX_OUT OMX_STRING componentName,
703 OMX_OUT OMX_VERSIONTYPE* componentVersion,
704 OMX_OUT OMX_VERSIONTYPE* specVersion,
705 OMX_OUT OMX_UUIDTYPE* componentUUID
706 )
707 {
708   if(m_state == OMX_StateInvalid)
709   {
710     DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
711     return OMX_ErrorInvalidState;
712   }
713   /* TBD -- Return the proper version */
714   if (specVersion)
715   {
716     specVersion->nVersion = OMX_SPEC_VERSION;
717   }
718   return OMX_ErrorNone;
719 }
720 /* ======================================================================
721 FUNCTION
722   omx_venc::SendCommand
723 
724 DESCRIPTION
725   Returns zero if all the buffers released..
726 
727 PARAMETERS
728   None.
729 
730 RETURN VALUE
731   true/false
732 
733 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)734 OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
735                                        OMX_IN OMX_COMMANDTYPE cmd,
736                                        OMX_IN OMX_U32 param1,
737                                        OMX_IN OMX_PTR cmdData
738                                       )
739 {
740   if(m_state == OMX_StateInvalid)
741   {
742     DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
743     return OMX_ErrorInvalidState;
744   }
745 
746   if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
747   {
748     if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
749     {
750       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
751       return OMX_ErrorBadPortIndex;
752     }
753   }
754   if(cmd == OMX_CommandMarkBuffer)
755   {
756     if(param1 != PORT_INDEX_IN)
757     {
758       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
759       return OMX_ErrorBadPortIndex;
760     }
761     if(!cmdData)
762     {
763       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
764       return OMX_ErrorBadParameter;
765     }
766   }
767 
768   post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
769   sem_wait(&m_cmd_lock);
770   return OMX_ErrorNone;
771 }
772 
773 /* ======================================================================
774 FUNCTION
775   omx_venc::SendCommand
776 
777 DESCRIPTION
778   Returns zero if all the buffers released..
779 
780 PARAMETERS
781   None.
782 
783 RETURN VALUE
784   true/false
785 
786 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)787 OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
788                                              OMX_IN OMX_COMMANDTYPE cmd,
789                                              OMX_IN OMX_U32 param1,
790                                              OMX_IN OMX_PTR cmdData
791                                             )
792 {
793   OMX_ERRORTYPE eRet = OMX_ErrorNone;
794   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
795   int bFlag = 1;
796 
797   if(cmd == OMX_CommandStateSet)
798   {
799     /***************************/
800     /* Current State is Loaded */
801     /***************************/
802     if(m_state == OMX_StateLoaded)
803     {
804       if(eState == OMX_StateIdle)
805       {
806         //if all buffers are allocated or all ports disabled
807         if(allocate_done() ||
808            ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
809         {
810           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
811         }
812         else
813         {
814           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
815           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
816           // Skip the event notification
817           bFlag = 0;
818         }
819       }
820       /* Requesting transition from Loaded to Loaded */
821       else if(eState == OMX_StateLoaded)
822       {
823         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n");
824         post_event(OMX_EventError,OMX_ErrorSameState,\
825                    OMX_COMPONENT_GENERATE_EVENT);
826         eRet = OMX_ErrorSameState;
827       }
828       /* Requesting transition from Loaded to WaitForResources */
829       else if(eState == OMX_StateWaitForResources)
830       {
831         /* Since error is None , we will post an event
832            at the end of this function definition */
833         DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
834       }
835       /* Requesting transition from Loaded to Executing */
836       else if(eState == OMX_StateExecuting)
837       {
838         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
839         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
840                    OMX_COMPONENT_GENERATE_EVENT);
841         eRet = OMX_ErrorIncorrectStateTransition;
842       }
843       /* Requesting transition from Loaded to Pause */
844       else if(eState == OMX_StatePause)
845       {
846         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
847         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
848                    OMX_COMPONENT_GENERATE_EVENT);
849         eRet = OMX_ErrorIncorrectStateTransition;
850       }
851       /* Requesting transition from Loaded to Invalid */
852       else if(eState == OMX_StateInvalid)
853       {
854         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
855         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
856         eRet = OMX_ErrorInvalidState;
857       }
858       else
859       {
860         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
861                           eState);
862         eRet = OMX_ErrorBadParameter;
863       }
864     }
865 
866     /***************************/
867     /* Current State is IDLE */
868     /***************************/
869     else if(m_state == OMX_StateIdle)
870     {
871       if(eState == OMX_StateLoaded)
872       {
873         if(release_done())
874         {
875           /*
876              Since error is None , we will post an event at the end
877              of this function definition
878           */
879           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
880           if(dev_stop() != 0)
881           {
882             DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
883             eRet = OMX_ErrorHardware;
884           }
885         }
886         else
887         {
888           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
889           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
890           // Skip the event notification
891           bFlag = 0;
892         }
893       }
894       /* Requesting transition from Idle to Executing */
895       else if(eState == OMX_StateExecuting)
896       {
897         if( dev_start() )
898         {
899           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
900           omx_report_error ();
901           eRet = OMX_ErrorHardware;
902         }
903         else
904         {
905           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
906           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
907           bFlag = 0;
908         }
909 
910 	dev_start_done();
911       }
912       /* Requesting transition from Idle to Idle */
913       else if(eState == OMX_StateIdle)
914       {
915         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
916         post_event(OMX_EventError,OMX_ErrorSameState,\
917                    OMX_COMPONENT_GENERATE_EVENT);
918         eRet = OMX_ErrorSameState;
919       }
920       /* Requesting transition from Idle to WaitForResources */
921       else if(eState == OMX_StateWaitForResources)
922       {
923         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
924         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
925                    OMX_COMPONENT_GENERATE_EVENT);
926         eRet = OMX_ErrorIncorrectStateTransition;
927       }
928       /* Requesting transition from Idle to Pause */
929       else if(eState == OMX_StatePause)
930       {
931         /*To pause the Video core we need to start the driver*/
932         if( dev_start() )
933         {
934           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
935           omx_report_error ();
936           eRet = OMX_ErrorHardware;
937         }
938         else
939         {
940           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
941           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
942           bFlag = 0;
943         }
944       }
945       /* Requesting transition from Idle to Invalid */
946       else if(eState == OMX_StateInvalid)
947       {
948         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
949         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
950         eRet = OMX_ErrorInvalidState;
951       }
952       else
953       {
954         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
955         eRet = OMX_ErrorBadParameter;
956       }
957     }
958 
959     /******************************/
960     /* Current State is Executing */
961     /******************************/
962     else if(m_state == OMX_StateExecuting)
963     {
964       /* Requesting transition from Executing to Idle */
965       if(eState == OMX_StateIdle)
966       {
967         /* Since error is None , we will post an event
968         at the end of this function definition
969         */
970         DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
971         //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
972         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
973         execute_omx_flush(OMX_ALL);
974         bFlag = 0;
975 	dev_stop_done();
976       }
977       /* Requesting transition from Executing to Paused */
978       else if(eState == OMX_StatePause)
979       {
980 
981         if(dev_pause())
982         {
983           DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
984           post_event(OMX_EventError,OMX_ErrorHardware,\
985                      OMX_COMPONENT_GENERATE_EVENT);
986           eRet = OMX_ErrorHardware;
987         }
988         else
989         {
990           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
991           DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n");
992           bFlag = 0;
993         }
994       }
995       /* Requesting transition from Executing to Loaded */
996       else if(eState == OMX_StateLoaded)
997       {
998         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
999         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1000                    OMX_COMPONENT_GENERATE_EVENT);
1001         eRet = OMX_ErrorIncorrectStateTransition;
1002       }
1003       /* Requesting transition from Executing to WaitForResources */
1004       else if(eState == OMX_StateWaitForResources)
1005       {
1006         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
1007         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1008                    OMX_COMPONENT_GENERATE_EVENT);
1009         eRet = OMX_ErrorIncorrectStateTransition;
1010       }
1011       /* Requesting transition from Executing to Executing */
1012       else if(eState == OMX_StateExecuting)
1013       {
1014         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
1015         post_event(OMX_EventError,OMX_ErrorSameState,\
1016                    OMX_COMPONENT_GENERATE_EVENT);
1017         eRet = OMX_ErrorSameState;
1018       }
1019       /* Requesting transition from Executing to Invalid */
1020       else if(eState == OMX_StateInvalid)
1021       {
1022         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
1023         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1024         eRet = OMX_ErrorInvalidState;
1025       }
1026       else
1027       {
1028         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
1029         eRet = OMX_ErrorBadParameter;
1030       }
1031     }
1032     /***************************/
1033     /* Current State is Pause  */
1034     /***************************/
1035     else if(m_state == OMX_StatePause)
1036     {
1037       /* Requesting transition from Pause to Executing */
1038       if(eState == OMX_StateExecuting)
1039       {
1040         DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1041         if( dev_resume() )
1042         {
1043           post_event(OMX_EventError,OMX_ErrorHardware,\
1044                      OMX_COMPONENT_GENERATE_EVENT);
1045           eRet = OMX_ErrorHardware;
1046         }
1047         else
1048         {
1049           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1050           DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n");
1051           post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE);
1052           bFlag = 0;
1053         }
1054       }
1055       /* Requesting transition from Pause to Idle */
1056       else if(eState == OMX_StateIdle)
1057       {
1058         /* Since error is None , we will post an event
1059         at the end of this function definition */
1060         DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1061         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1062         execute_omx_flush(OMX_ALL);
1063         bFlag = 0;
1064       }
1065       /* Requesting transition from Pause to loaded */
1066       else if(eState == OMX_StateLoaded)
1067       {
1068         DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
1069         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1070                    OMX_COMPONENT_GENERATE_EVENT);
1071         eRet = OMX_ErrorIncorrectStateTransition;
1072       }
1073       /* Requesting transition from Pause to WaitForResources */
1074       else if(eState == OMX_StateWaitForResources)
1075       {
1076         DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
1077         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1078                    OMX_COMPONENT_GENERATE_EVENT);
1079         eRet = OMX_ErrorIncorrectStateTransition;
1080       }
1081       /* Requesting transition from Pause to Pause */
1082       else if(eState == OMX_StatePause)
1083       {
1084         DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
1085         post_event(OMX_EventError,OMX_ErrorSameState,\
1086                    OMX_COMPONENT_GENERATE_EVENT);
1087         eRet = OMX_ErrorSameState;
1088       }
1089       /* Requesting transition from Pause to Invalid */
1090       else if(eState == OMX_StateInvalid)
1091       {
1092         DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
1093         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1094         eRet = OMX_ErrorInvalidState;
1095       }
1096       else
1097       {
1098         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
1099         eRet = OMX_ErrorBadParameter;
1100       }
1101     }
1102     /***************************/
1103     /* Current State is WaitForResources  */
1104     /***************************/
1105     else if(m_state == OMX_StateWaitForResources)
1106     {
1107       /* Requesting transition from WaitForResources to Loaded */
1108       if(eState == OMX_StateLoaded)
1109       {
1110         /* Since error is None , we will post an event
1111         at the end of this function definition */
1112         DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
1113       }
1114       /* Requesting transition from WaitForResources to WaitForResources */
1115       else if(eState == OMX_StateWaitForResources)
1116       {
1117         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
1118         post_event(OMX_EventError,OMX_ErrorSameState,
1119                    OMX_COMPONENT_GENERATE_EVENT);
1120         eRet = OMX_ErrorSameState;
1121       }
1122       /* Requesting transition from WaitForResources to Executing */
1123       else if(eState == OMX_StateExecuting)
1124       {
1125         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
1126         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1127                    OMX_COMPONENT_GENERATE_EVENT);
1128         eRet = OMX_ErrorIncorrectStateTransition;
1129       }
1130       /* Requesting transition from WaitForResources to Pause */
1131       else if(eState == OMX_StatePause)
1132       {
1133         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
1134         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1135                    OMX_COMPONENT_GENERATE_EVENT);
1136         eRet = OMX_ErrorIncorrectStateTransition;
1137       }
1138       /* Requesting transition from WaitForResources to Invalid */
1139       else if(eState == OMX_StateInvalid)
1140       {
1141         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
1142         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1143         eRet = OMX_ErrorInvalidState;
1144       }
1145       /* Requesting transition from WaitForResources to Loaded -
1146       is NOT tested by Khronos TS */
1147 
1148     }
1149     else
1150     {
1151       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
1152       eRet = OMX_ErrorBadParameter;
1153     }
1154   }
1155   /********************************/
1156   /* Current State is Invalid */
1157   /*******************************/
1158   else if(m_state == OMX_StateInvalid)
1159   {
1160     /* State Transition from Inavlid to any state */
1161     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
1162                   || OMX_StateIdle || OMX_StateExecuting
1163                   || OMX_StatePause || OMX_StateInvalid))
1164     {
1165       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
1166       post_event(OMX_EventError,OMX_ErrorInvalidState,\
1167                  OMX_COMPONENT_GENERATE_EVENT);
1168       eRet = OMX_ErrorInvalidState;
1169     }
1170   }
1171   else if(cmd == OMX_CommandFlush)
1172   {
1173     if(0 == param1 || OMX_ALL == param1)
1174     {
1175       BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1176     }
1177     if(1 == param1 || OMX_ALL == param1)
1178     {
1179       //generate output flush event only.
1180       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1181     }
1182 
1183     execute_omx_flush(param1);
1184     bFlag = 0;
1185   }
1186   else if( cmd == OMX_CommandPortEnable)
1187   {
1188     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1189     {
1190       m_sInPortDef.bEnabled = OMX_TRUE;
1191 
1192       if( (m_state == OMX_StateLoaded &&
1193            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1194           || allocate_input_done())
1195       {
1196         post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
1197                    OMX_COMPONENT_GENERATE_EVENT);
1198       }
1199       else
1200       {
1201         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1202         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1203         // Skip the event notification
1204         bFlag = 0;
1205       }
1206     }
1207     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1208     {
1209       m_sOutPortDef.bEnabled = OMX_TRUE;
1210 
1211       if( (m_state == OMX_StateLoaded &&
1212            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1213           || (allocate_output_done()))
1214       {
1215         post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
1216                    OMX_COMPONENT_GENERATE_EVENT);
1217 
1218       }
1219       else
1220       {
1221         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1222         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1223         // Skip the event notification
1224         bFlag = 0;
1225       }
1226     }
1227   }
1228   else if(cmd == OMX_CommandPortDisable)
1229   {
1230     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1231     {
1232       m_sInPortDef.bEnabled = OMX_FALSE;
1233       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1234          && release_input_done())
1235       {
1236         post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
1237                    OMX_COMPONENT_GENERATE_EVENT);
1238       }
1239       else
1240       {
1241         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1242         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1243         {
1244           execute_omx_flush(PORT_INDEX_IN);
1245         }
1246 
1247         // Skip the event notification
1248         bFlag = 0;
1249       }
1250     }
1251     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1252     {
1253       m_sOutPortDef.bEnabled = OMX_FALSE;
1254 
1255       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1256          && release_output_done())
1257       {
1258         post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
1259                    OMX_COMPONENT_GENERATE_EVENT);
1260       }
1261       else
1262       {
1263         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1264         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1265         {
1266           execute_omx_flush(PORT_INDEX_OUT);
1267         }
1268         // Skip the event notification
1269         bFlag = 0;
1270 
1271       }
1272     }
1273   }
1274   else
1275   {
1276     DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
1277     eRet = OMX_ErrorNotImplemented;
1278   }
1279   if(eRet == OMX_ErrorNone && bFlag)
1280   {
1281     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1282   }
1283   sem_post(&m_cmd_lock);
1284   return eRet;
1285 }
1286 
1287 /* ======================================================================
1288 FUNCTION
1289   omx_venc::ExecuteOmxFlush
1290 
1291 DESCRIPTION
1292   Executes the OMX flush.
1293 
1294 PARAMETERS
1295   flushtype - input flush(1)/output flush(0)/ both.
1296 
1297 RETURN VALUE
1298   true/false
1299 
1300 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)1301 bool omx_video::execute_omx_flush(OMX_U32 flushType)
1302 {
1303   bool bRet = false;
1304   DEBUG_PRINT_LOW("\n execute_omx_flush -  %d\n", flushType);
1305   if(flushType == 0 || flushType == OMX_ALL)
1306   {
1307     input_flush_progress = true;
1308     //flush input only
1309     bRet = execute_input_flush();
1310   }
1311   if(flushType == 1 || flushType == OMX_ALL)
1312   {
1313     //flush output only
1314     output_flush_progress = true;
1315     bRet = execute_output_flush();
1316   }
1317   return bRet;
1318 }
1319 /*=========================================================================
1320 FUNCTION : execute_output_flush
1321 
1322 DESCRIPTION
1323   Executes the OMX flush at OUTPUT PORT.
1324 
1325 PARAMETERS
1326   None.
1327 
1328 RETURN VALUE
1329   true/false
1330 ==========================================================================*/
execute_output_flush(void)1331 bool omx_video::execute_output_flush(void)
1332 {
1333   unsigned      p1 = 0; // Parameter - 1
1334   unsigned      p2 = 0; // Parameter - 2
1335   unsigned      ident = 0;
1336   bool bRet = true;
1337 
1338   /*Generate FBD for all Buffers in the FTBq*/
1339   DEBUG_PRINT_LOW("\n execute_output_flush\n");
1340   pthread_mutex_lock(&m_lock);
1341   while(m_ftb_q.m_size)
1342   {
1343     m_ftb_q.pop_entry(&p1,&p2,&ident);
1344 
1345     if(ident == OMX_COMPONENT_GENERATE_FTB )
1346     {
1347       pending_output_buffers++;
1348       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1349     }
1350     else if(ident == OMX_COMPONENT_GENERATE_FBD)
1351     {
1352       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1353     }
1354   }
1355 
1356   pthread_mutex_unlock(&m_lock);
1357   /*Check if there are buffers with the Driver*/
1358   if(dev_flush(PORT_INDEX_OUT))
1359   {
1360     DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
1361     return false;
1362   }
1363 
1364   return bRet;
1365 }
1366 /*=========================================================================
1367 FUNCTION : execute_input_flush
1368 
1369 DESCRIPTION
1370   Executes the OMX flush at INPUT PORT.
1371 
1372 PARAMETERS
1373   None.
1374 
1375 RETURN VALUE
1376   true/false
1377 ==========================================================================*/
execute_input_flush(void)1378 bool omx_video::execute_input_flush(void)
1379 {
1380   unsigned      p1 = 0; // Parameter - 1
1381   unsigned      p2 = 0; // Parameter - 2
1382   unsigned      ident = 0;
1383   bool bRet = true;
1384 
1385   /*Generate EBD for all Buffers in the ETBq*/
1386   DEBUG_PRINT_LOW("\n execute_input_flush\n");
1387 
1388   pthread_mutex_lock(&m_lock);
1389   while(m_etb_q.m_size)
1390   {
1391     m_etb_q.pop_entry(&p1,&p2,&ident);
1392     if(ident == OMX_COMPONENT_GENERATE_ETB)
1393     {
1394       pending_input_buffers++;
1395       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1396     }
1397     else if(ident == OMX_COMPONENT_GENERATE_EBD)
1398     {
1399       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1400     }
1401     else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ)
1402     {
1403       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1404     }
1405   }
1406   if(mUseProxyColorFormat) {
1407     if(psource_frame) {
1408       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1409       psource_frame = NULL;
1410     }
1411     while(m_opq_meta_q.m_size) {
1412       unsigned p1,p2,id;
1413       m_opq_meta_q.pop_entry(&p1,&p2,&id);
1414       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1415          (OMX_BUFFERHEADERTYPE  *)p1);
1416     }
1417     if(pdest_frame){
1418       m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0);
1419       pdest_frame = NULL;
1420     }
1421   }
1422   pthread_mutex_unlock(&m_lock);
1423   /*Check if there are buffers with the Driver*/
1424   if(dev_flush(PORT_INDEX_IN))
1425   {
1426     DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
1427     return false;
1428   }
1429 
1430   return bRet;
1431 }
1432 
1433 
1434 /* ======================================================================
1435 FUNCTION
1436   omx_venc::SendCommandEvent
1437 
1438 DESCRIPTION
1439   Send the event to decoder pipe.  This is needed to generate the callbacks
1440   in decoder thread context.
1441 
1442 PARAMETERS
1443   None.
1444 
1445 RETURN VALUE
1446   true/false
1447 
1448 ========================================================================== */
post_event(unsigned int p1,unsigned int p2,unsigned int id)1449 bool omx_video::post_event(unsigned int p1,
1450                            unsigned int p2,
1451                            unsigned int id)
1452 {
1453   bool bRet      =                      false;
1454 
1455 
1456   pthread_mutex_lock(&m_lock);
1457 
1458   if( id == OMX_COMPONENT_GENERATE_FTB || \
1459       (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
1460   {
1461     m_ftb_q.insert_entry(p1,p2,id);
1462   }
1463   else if((id == m_input_msg_id) \
1464           || (id == OMX_COMPONENT_GENERATE_EBD))
1465   {
1466     m_etb_q.insert_entry(p1,p2,id);
1467   }
1468   else
1469   {
1470     m_cmd_q.insert_entry(p1,p2,id);
1471   }
1472 
1473   bRet = true;
1474   DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
1475   post_message(this, id);
1476   pthread_mutex_unlock(&m_lock);
1477 
1478   return bRet;
1479 }
1480 
1481 /* ======================================================================
1482 FUNCTION
1483   omx_venc::GetParameter
1484 
1485 DESCRIPTION
1486   OMX Get Parameter method implementation
1487 
1488 PARAMETERS
1489   <TBD>.
1490 
1491 RETURN VALUE
1492   Error None if successful.
1493 
1494 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)1495 OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
1496                                         OMX_IN OMX_INDEXTYPE paramIndex,
1497                                         OMX_INOUT OMX_PTR     paramData)
1498 {
1499   OMX_ERRORTYPE eRet = OMX_ErrorNone;
1500   unsigned int height=0,width = 0;
1501 
1502   DEBUG_PRINT_LOW("get_parameter: \n");
1503   if(m_state == OMX_StateInvalid)
1504   {
1505     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
1506     return OMX_ErrorInvalidState;
1507   }
1508   if(paramData == NULL)
1509   {
1510     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
1511     return OMX_ErrorBadParameter;
1512   }
1513   switch(paramIndex)
1514   {
1515   case OMX_IndexParamPortDefinition:
1516     {
1517       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1518       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1519 
1520       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
1521       if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1522       {
1523         DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
1524             m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
1525             m_sInPortDef.nBufferCountActual);
1526         memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
1527 #ifdef _ANDROID_ICS_
1528         if(meta_mode_enable)
1529         {
1530           portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
1531         }
1532         if(secure_session) {
1533           portDefn->format.video.eColorFormat =
1534             (OMX_COLOR_FORMATTYPE)secure_color_format;
1535         }
1536         else if (mUseProxyColorFormat) {
1537             portDefn->format.video.eColorFormat =
1538               (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1539         }
1540 #endif
1541       }
1542       else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1543       {
1544         dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
1545                          &m_sOutPortDef.nBufferCountActual,
1546                          &m_sOutPortDef.nBufferSize,
1547                          m_sOutPortDef.nPortIndex);
1548         DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
1549             m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
1550             m_sOutPortDef.nBufferCountActual);
1551         memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
1552       }
1553       else
1554       {
1555         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1556         eRet = OMX_ErrorBadPortIndex;
1557       }
1558       break;
1559     }
1560   case OMX_IndexParamVideoInit:
1561     {
1562       OMX_PORT_PARAM_TYPE *portParamType =
1563       (OMX_PORT_PARAM_TYPE *) paramData;
1564       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
1565 
1566       memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
1567       break;
1568     }
1569   case OMX_IndexParamVideoPortFormat:
1570     {
1571       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
1572       (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1573       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
1574 
1575       if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1576       {
1577           int index = portFmt->nIndex;
1578 
1579           if (index > 1) {
1580               eRet = OMX_ErrorNoMore;
1581           } else {
1582               memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
1583 #ifdef _ANDROID_ICS_
1584               if (index == 1) {
1585                   //we support two formats
1586                   //index 0 - YUV420SP
1587                   //index 1 - opaque which internally maps to YUV420SP.
1588                   //this can be extended in the future
1589                   portFmt->nIndex = index; //restore index set from client
1590                   portFmt->eColorFormat =
1591                     (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1592               }
1593           }
1594 #endif
1595       }
1596       else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1597       {
1598         memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
1599       }
1600       else
1601       {
1602         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1603         eRet = OMX_ErrorBadPortIndex;
1604       }
1605       break;
1606     }
1607   case OMX_IndexParamVideoBitrate:
1608     {
1609       OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1610       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
1611 
1612       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1613       {
1614         memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
1615       }
1616       else
1617       {
1618         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1619         eRet = OMX_ErrorBadPortIndex;
1620       }
1621 
1622       break;
1623     }
1624   case OMX_IndexParamVideoMpeg4:
1625     {
1626       OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1627       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
1628       memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
1629       break;
1630     }
1631   case OMX_IndexParamVideoH263:
1632     {
1633       OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1634       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
1635       memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
1636       break;
1637     }
1638   case OMX_IndexParamVideoAvc:
1639     {
1640       OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1641       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
1642       memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
1643       break;
1644     }
1645   case OMX_IndexParamVideoProfileLevelQuerySupported:
1646     {
1647       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1648       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
1649       eRet = get_supported_profile_level(pParam);
1650       if(eRet)
1651         DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
1652                           pParam->eProfile, pParam->eLevel);
1653       break;
1654      }
1655   case OMX_IndexParamVideoProfileLevelCurrent:
1656     {
1657       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1658       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
1659       memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
1660       break;
1661     }
1662     /*Component should support this port definition*/
1663   case OMX_IndexParamAudioInit:
1664     {
1665       OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1666       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
1667       memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
1668       break;
1669     }
1670     /*Component should support this port definition*/
1671   case OMX_IndexParamImageInit:
1672     {
1673       OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1674       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
1675       memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
1676       break;
1677 
1678     }
1679     /*Component should support this port definition*/
1680   case OMX_IndexParamOtherInit:
1681     {
1682       DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
1683       eRet =OMX_ErrorUnsupportedIndex;
1684       break;
1685     }
1686   case OMX_IndexParamStandardComponentRole:
1687     {
1688       OMX_PARAM_COMPONENTROLETYPE *comp_role;
1689       comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1690       comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
1691       comp_role->nSize = sizeof(*comp_role);
1692 
1693       DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
1694       if(NULL != comp_role->cRole)
1695       {
1696         strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
1697       }
1698       else
1699       {
1700         DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex);
1701         eRet =OMX_ErrorBadParameter;
1702       }
1703       break;
1704     }
1705     /* Added for parameter test */
1706   case OMX_IndexParamPriorityMgmt:
1707     {
1708 
1709       OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
1710       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
1711       memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
1712       break;
1713     }
1714     /* Added for parameter test */
1715   case OMX_IndexParamCompBufferSupplier:
1716     {
1717       OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
1718       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
1719       if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN)
1720       {
1721         memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
1722       }
1723       else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT)
1724       {
1725         memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
1726       }
1727       else
1728       {
1729         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1730         eRet = OMX_ErrorBadPortIndex;
1731       }
1732       break;
1733     }
1734 
1735   case OMX_IndexParamVideoQuantization:
1736     {
1737       OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
1738       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n");
1739       memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
1740       break;
1741     }
1742 
1743     case OMX_IndexParamVideoErrorCorrection:
1744     {
1745       OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1746       DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n");
1747       errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
1748       errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
1749       errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
1750       break;
1751     }
1752   case OMX_IndexParamVideoIntraRefresh:
1753     {
1754       OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1755       DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n");
1756       DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n");
1757       intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
1758       intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
1759       break;
1760     }
1761   case OMX_QcomIndexPortDefn:
1762     //TODO
1763     break;
1764   case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
1765    {
1766         OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
1767         DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n");
1768         pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
1769         pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
1770         pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
1771         pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
1772         pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
1773         pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
1774         pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
1775         pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
1776         m_use_input_pmem = OMX_TRUE;
1777         DEBUG_PRINT_LOW("Supporting capability index in encoder node");
1778         break;
1779    }
1780 #ifndef MAX_RES_720P
1781   case OMX_QcomIndexParamIndexExtraDataType:
1782     {
1783       DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
1784       QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1785       if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
1786       {
1787         if (pParam->nPortIndex == PORT_INDEX_OUT)
1788         {
1789           pParam->bEnabled =
1790              (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0);
1791           DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
1792         }
1793         else
1794         {
1795           DEBUG_PRINT_ERROR("get_parameter: slice information is "
1796               "valid for output port only");
1797           eRet =OMX_ErrorUnsupportedIndex;
1798         }
1799       }
1800       else
1801       {
1802         DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), "
1803             "only slice information extradata is supported", pParam->nIndex);
1804         eRet =OMX_ErrorUnsupportedIndex;
1805       }
1806       break;
1807     }
1808 #endif
1809   case QOMX_IndexParamVideoSyntaxHdr:
1810     {
1811        DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
1812        QOMX_EXTNINDEX_PARAMTYPE* pParam =
1813           reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
1814        BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1815        if(dev_loaded_start())
1816        {
1817          DEBUG_PRINT_LOW("device start successful");
1818        }
1819        else
1820        {
1821          DEBUG_PRINT_ERROR("device start failed");
1822          BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1823          return OMX_ErrorHardware;
1824        }
1825        if(dev_get_seq_hdr(pParam->pData,
1826             (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
1827             (unsigned *)&pParam->nDataSize))
1828        {
1829          DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)",
1830             pParam->nDataSize);
1831          for (unsigned i = 0; i < pParam->nDataSize; i++) {
1832            DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
1833          }
1834        }
1835        else
1836        {
1837          DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
1838          eRet = OMX_ErrorHardware;
1839        }
1840        BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1841        if(dev_loaded_stop())
1842        {
1843          DEBUG_PRINT_LOW("device stop successful");
1844        }
1845        else
1846        {
1847          DEBUG_PRINT_ERROR("device stop failed");
1848          BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1849          eRet = OMX_ErrorHardware;
1850        }
1851        break;
1852     }
1853   case OMX_IndexParamVideoSliceFMO:
1854   default:
1855     {
1856       DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex);
1857       eRet =OMX_ErrorUnsupportedIndex;
1858       break;
1859     }
1860 
1861   }
1862 
1863   return eRet;
1864 
1865 }
1866 /* ======================================================================
1867 FUNCTION
1868   omx_video::GetConfig
1869 
1870 DESCRIPTION
1871   OMX Get Config Method implementation.
1872 
1873 PARAMETERS
1874   <TBD>.
1875 
1876 RETURN VALUE
1877   OMX Error None if successful.
1878 
1879 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)1880 OMX_ERRORTYPE  omx_video::get_config(OMX_IN OMX_HANDLETYPE      hComp,
1881                                      OMX_IN OMX_INDEXTYPE configIndex,
1882                                      OMX_INOUT OMX_PTR     configData)
1883 {
1884   ////////////////////////////////////////////////////////////////
1885   // Supported Config Index           Type
1886   // =============================================================
1887   // OMX_IndexConfigVideoBitrate      OMX_VIDEO_CONFIG_BITRATETYPE
1888   // OMX_IndexConfigVideoFramerate    OMX_CONFIG_FRAMERATETYPE
1889   // OMX_IndexConfigCommonRotate      OMX_CONFIG_ROTATIONTYPE
1890   ////////////////////////////////////////////////////////////////
1891 
1892   if(configData == NULL)
1893   {
1894     DEBUG_PRINT_ERROR("ERROR: param is null");
1895     return OMX_ErrorBadParameter;
1896   }
1897 
1898   if(m_state == OMX_StateInvalid)
1899   {
1900     DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
1901     return OMX_ErrorIncorrectStateOperation;
1902   }
1903 
1904   //@todo need to validate params
1905   switch(configIndex)
1906   {
1907   case OMX_IndexConfigVideoBitrate:
1908     {
1909       OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
1910       memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
1911       break;
1912     }
1913   case OMX_IndexConfigVideoFramerate:
1914     {
1915       OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
1916       memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
1917       break;
1918     }
1919   case OMX_IndexConfigCommonRotate:
1920     {
1921       OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1922       memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
1923       break;
1924     }
1925   case QOMX_IndexConfigVideoIntraperiod:
1926     {
1927       DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n");
1928       QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
1929       memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
1930       break;
1931     }
1932   default:
1933     DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
1934     return OMX_ErrorUnsupportedIndex;
1935   }
1936   return OMX_ErrorNone;
1937 
1938 }
1939 
1940 /* ======================================================================
1941 FUNCTION
1942   omx_video::GetExtensionIndex
1943 
1944 DESCRIPTION
1945   OMX GetExtensionIndex method implementaion.  <TBD>
1946 
1947 PARAMETERS
1948   <TBD>.
1949 
1950 RETURN VALUE
1951   OMX Error None if everything successful.
1952 
1953 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)1954 OMX_ERRORTYPE  omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
1955                                               OMX_IN OMX_STRING      paramName,
1956                                               OMX_OUT OMX_INDEXTYPE* indexType)
1957 {
1958   char *extns[] = {
1959     "OMX.QCOM.index.param.SliceDeliveryMode",
1960     "OMX.google.android.index.storeMetaDataInBuffers",
1961     "OMX.google.android.index.prependSPSPPSToIDRFrames",
1962     "OMX.google.android.index.setVUIStreamRestrictFlag"
1963   };
1964 
1965   if(m_state == OMX_StateInvalid)
1966   {
1967     DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n");
1968     return OMX_ErrorInvalidState;
1969   }
1970 #ifdef MAX_RES_1080P
1971   if (!strncmp(paramName, extns[0], strlen(extns[0]))) {
1972     *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
1973     return OMX_ErrorNone;
1974   }
1975 #endif
1976 #ifdef _ANDROID_ICS_
1977   if (!strncmp(paramName, extns[1], strlen(extns[1]))) {
1978         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoEncodeMetaBufferMode;
1979         return OMX_ErrorNone;
1980   } else if (!strncmp(paramName, extns[2], strlen(extns[2]))) {
1981         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
1982         return OMX_ErrorNone;
1983   } else if (!strncmp(paramName, extns[3], strlen(extns[3]))) {
1984         *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag;
1985         return OMX_ErrorNone;
1986   }
1987 #endif
1988   return OMX_ErrorNotImplemented;
1989 }
1990 
1991 /* ======================================================================
1992 FUNCTION
1993   omx_video::GetState
1994 
1995 DESCRIPTION
1996   Returns the state information back to the caller.<TBD>
1997 
1998 PARAMETERS
1999   <TBD>.
2000 
2001 RETURN VALUE
2002   Error None if everything is successful.
2003 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)2004 OMX_ERRORTYPE  omx_video::get_state(OMX_IN OMX_HANDLETYPE  hComp,
2005                                     OMX_OUT OMX_STATETYPE* state)
2006 {
2007   *state = m_state;
2008   DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
2009   return OMX_ErrorNone;
2010 }
2011 
2012 /* ======================================================================
2013 FUNCTION
2014   omx_video::ComponentTunnelRequest
2015 
2016 DESCRIPTION
2017   OMX Component Tunnel Request method implementation. <TBD>
2018 
2019 PARAMETERS
2020   None.
2021 
2022 RETURN VALUE
2023   OMX Error None if everything successful.
2024 
2025 ========================================================================== */
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)2026 OMX_ERRORTYPE  omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
2027                                                    OMX_IN OMX_U32                        port,
2028                                                    OMX_IN OMX_HANDLETYPE        peerComponent,
2029                                                    OMX_IN OMX_U32                    peerPort,
2030                                                    OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
2031 {
2032   DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n");
2033   return OMX_ErrorNotImplemented;
2034 }
2035 
2036 /* ======================================================================
2037 FUNCTION
2038   omx_video::UseInputBuffer
2039 
2040 DESCRIPTION
2041   Helper function for Use buffer in the input pin
2042 
2043 PARAMETERS
2044   None.
2045 
2046 RETURN VALUE
2047   true/false
2048 
2049 ========================================================================== */
use_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,OMX_IN OMX_U8 * buffer)2050 OMX_ERRORTYPE  omx_video::use_input_buffer(
2051                                           OMX_IN OMX_HANDLETYPE            hComp,
2052                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2053                                           OMX_IN OMX_U32                   port,
2054                                           OMX_IN OMX_PTR                   appData,
2055                                           OMX_IN OMX_U32                   bytes,
2056                                           OMX_IN OMX_U8*                   buffer)
2057 {
2058   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2059 
2060   unsigned   i = 0;
2061   unsigned char *buf_addr = NULL;
2062 
2063   DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer);
2064   if(bytes != m_sInPortDef.nBufferSize || secure_session)
2065   {
2066     DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! "
2067                       "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize);
2068     return OMX_ErrorBadParameter;
2069   }
2070 
2071   if(!m_inp_mem_ptr)
2072   {
2073     input_use_buffer = true;
2074     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
2075                     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
2076     if(m_inp_mem_ptr == NULL)
2077     {
2078       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
2079       return OMX_ErrorInsufficientResources;
2080     }
2081 
2082 
2083     m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
2084     if(m_pInput_pmem == NULL)
2085     {
2086       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
2087       return OMX_ErrorInsufficientResources;
2088     }
2089 #ifdef USE_ION
2090     m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
2091     if(m_pInput_ion == NULL)
2092     {
2093       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
2094       return OMX_ErrorInsufficientResources;
2095     }
2096 #endif
2097 
2098     for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2099     {
2100       m_pInput_pmem[i].fd = -1;
2101 #ifdef USE_ION
2102       m_pInput_ion[i].ion_device_fd =-1;
2103       m_pInput_ion[i].fd_ion_data.fd =-1;
2104       m_pInput_ion[i].ion_alloc_data.handle=NULL;
2105 #endif
2106     }
2107 
2108   }
2109 
2110   for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2111   {
2112     if(BITMASK_ABSENT(&m_inp_bm_count,i))
2113     {
2114       break;
2115     }
2116   }
2117 
2118   if(i < m_sInPortDef.nBufferCountActual)
2119   {
2120 
2121     *bufferHdr = (m_inp_mem_ptr + i);
2122     BITMASK_SET(&m_inp_bm_count,i);
2123 
2124     (*bufferHdr)->pBuffer           = (OMX_U8 *)buffer;
2125     (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
2126     (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
2127     (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
2128     (*bufferHdr)->pAppPrivate       = appData;
2129     (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
2130 
2131     if(!m_use_input_pmem)
2132     {
2133 #ifdef USE_ION
2134       m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
2135                                       &m_pInput_ion[i].ion_alloc_data,
2136                                       &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2137       if(m_pInput_ion[i].ion_device_fd < 0) {
2138         DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2139         return OMX_ErrorInsufficientResources;
2140       }
2141       m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
2142 #else
2143       m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2144       if(m_pInput_pmem[i].fd == 0)
2145       {
2146         m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2147       }
2148 
2149       if(m_pInput_pmem[i] .fd < 0)
2150       {
2151         DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
2152         return OMX_ErrorInsufficientResources;
2153       }
2154 #endif
2155       m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2156       m_pInput_pmem[i].offset = 0;
2157       m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
2158                                                       MAP_SHARED,m_pInput_pmem[i].fd,0);
2159 
2160       if(m_pInput_pmem[i].buffer == MAP_FAILED)
2161       {
2162         DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
2163         close(m_pInput_pmem[i].fd);
2164 #ifdef USE_ION
2165         free_ion_memory(&m_pInput_ion[i]);
2166 #endif
2167         return OMX_ErrorInsufficientResources;
2168       }
2169     }
2170     else
2171     {
2172       OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
2173       DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
2174 
2175       if(pParam)
2176       {
2177         m_pInput_pmem[i].fd = pParam->pmem_fd;
2178         m_pInput_pmem[i].offset = pParam->offset;
2179         m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2180         m_pInput_pmem[i].buffer = (unsigned char *)buffer;
2181         DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
2182             pParam->pmem_fd, pParam->offset);
2183       }
2184       else
2185       {
2186         DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
2187         return OMX_ErrorBadParameter;
2188       }
2189     }
2190 
2191     DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
2192                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
2193     if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)
2194     {
2195       DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf");
2196       return OMX_ErrorInsufficientResources;
2197     }
2198   }
2199   else
2200   {
2201     DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for "
2202                       "index = %u", i);
2203     eRet = OMX_ErrorInsufficientResources;
2204   }
2205 
2206   return eRet;
2207 }
2208 
2209 
2210 
2211 /* ======================================================================
2212 FUNCTION
2213   omx_video::UseOutputBuffer
2214 
2215 DESCRIPTION
2216   Helper function for Use buffer in the input pin
2217 
2218 PARAMETERS
2219   None.
2220 
2221 RETURN VALUE
2222   true/false
2223 
2224 ========================================================================== */
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)2225 OMX_ERRORTYPE  omx_video::use_output_buffer(
2226                                            OMX_IN OMX_HANDLETYPE            hComp,
2227                                            OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2228                                            OMX_IN OMX_U32                   port,
2229                                            OMX_IN OMX_PTR                   appData,
2230                                            OMX_IN OMX_U32                   bytes,
2231                                            OMX_IN OMX_U8*                   buffer)
2232 {
2233   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2234   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
2235   unsigned                         i= 0; // Temporary counter
2236   unsigned char *buf_addr = NULL;
2237 
2238   DEBUG_PRINT_HIGH("\n Inside use_output_buffer()");
2239   if(bytes != m_sOutPortDef.nBufferSize || secure_session)
2240   {
2241     DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! "
2242                       "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize);
2243     return OMX_ErrorBadParameter;
2244   }
2245 
2246   if(!m_out_mem_ptr)
2247   {
2248     output_use_buffer = true;
2249     int nBufHdrSize        = 0;
2250 
2251     DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual);
2252     nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
2253     /*
2254      * Memory for output side involves the following:
2255      * 1. Array of Buffer Headers
2256      * 2. Bitmask array to hold the buffer allocation details
2257      * In order to minimize the memory management entire allocation
2258      * is done in one step.
2259      */
2260     //OMX Buffer header
2261     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
2262     if(m_out_mem_ptr == NULL)
2263     {
2264       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr");
2265       return OMX_ErrorInsufficientResources;
2266     }
2267 
2268     m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
2269     if(m_pOutput_pmem == NULL)
2270     {
2271       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
2272       return OMX_ErrorInsufficientResources;
2273     }
2274 #ifdef USE_ION
2275     m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
2276     if(m_pOutput_ion == NULL)
2277     {
2278       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
2279       return OMX_ErrorInsufficientResources;
2280     }
2281 #endif
2282     if(m_out_mem_ptr)
2283     {
2284       bufHdr          =  m_out_mem_ptr;
2285       DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
2286       // Settting the entire storage nicely
2287       for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
2288       {
2289         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
2290         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
2291         bufHdr->nAllocLen          = bytes;
2292         bufHdr->nFilledLen         = 0;
2293         bufHdr->pAppPrivate        = appData;
2294         bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
2295         bufHdr->pBuffer            = NULL;
2296         bufHdr++;
2297         m_pOutput_pmem[i].fd = -1;
2298 #ifdef USE_ION
2299         m_pOutput_ion[i].ion_device_fd =-1;
2300         m_pOutput_ion[i].fd_ion_data.fd=-1;
2301         m_pOutput_ion[i].ion_alloc_data.handle =NULL;
2302 #endif
2303       }
2304     }
2305     else
2306     {
2307       DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr);
2308       eRet =  OMX_ErrorInsufficientResources;
2309     }
2310   }
2311 
2312   for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
2313   {
2314     if(BITMASK_ABSENT(&m_out_bm_count,i))
2315     {
2316       break;
2317     }
2318   }
2319 
2320   if(eRet == OMX_ErrorNone)
2321   {
2322     if(i < m_sOutPortDef.nBufferCountActual)
2323     {
2324       *bufferHdr = (m_out_mem_ptr + i );
2325       (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
2326 	  (*bufferHdr)->pAppPrivate = appData;
2327       BITMASK_SET(&m_out_bm_count,i);
2328 
2329       if(!m_use_output_pmem)
2330       {
2331 #ifdef USE_ION
2332         m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
2333                                          m_sOutPortDef.nBufferSize,
2334                                          &m_pOutput_ion[i].ion_alloc_data,
2335                                          &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2336       if(m_pOutput_ion[i].ion_device_fd < 0) {
2337         DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2338         return OMX_ErrorInsufficientResources;
2339       }
2340       m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
2341 #else
2342         m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2343 
2344         if(m_pOutput_pmem[i].fd == 0)
2345         {
2346           m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2347         }
2348 
2349         if(m_pOutput_pmem[i].fd < 0)
2350         {
2351           DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
2352           return OMX_ErrorInsufficientResources;
2353         }
2354 #endif
2355         m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2356         m_pOutput_pmem[i].offset = 0;
2357         m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
2358                                                          MAP_SHARED,m_pOutput_pmem[i].fd,0);
2359         if(m_pOutput_pmem[i].buffer == MAP_FAILED)
2360         {
2361           DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
2362           close(m_pOutput_pmem[i].fd);
2363 #ifdef USE_ION
2364           free_ion_memory(&m_pOutput_ion[i]);
2365 #endif
2366           return OMX_ErrorInsufficientResources;
2367         }
2368       }
2369       else
2370       {
2371         OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
2372         DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam);
2373 
2374         if(pParam)
2375         {
2376           DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
2377           m_pOutput_pmem[i].fd = pParam->pmem_fd;
2378           m_pOutput_pmem[i].offset = pParam->offset;
2379           m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2380           m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
2381         }
2382         else
2383         {
2384           DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
2385           return OMX_ErrorBadParameter;
2386         }
2387         buf_addr = (unsigned char *)buffer;
2388       }
2389 
2390       DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
2391                 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
2392       if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
2393       {
2394         DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
2395         return OMX_ErrorInsufficientResources;
2396       }
2397     }
2398     else
2399     {
2400       DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
2401                       "index = %u", i);
2402       eRet = OMX_ErrorInsufficientResources;
2403     }
2404   }
2405   return eRet;
2406 }
2407 
2408 
2409 /* ======================================================================
2410 FUNCTION
2411   omx_video::UseBuffer
2412 
2413 DESCRIPTION
2414   OMX Use Buffer method implementation.
2415 
2416 PARAMETERS
2417   <TBD>.
2418 
2419 RETURN VALUE
2420   OMX Error None , if everything successful.
2421 
2422 ========================================================================== */
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)2423 OMX_ERRORTYPE  omx_video::use_buffer(
2424                                     OMX_IN OMX_HANDLETYPE            hComp,
2425                                     OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2426                                     OMX_IN OMX_U32                   port,
2427                                     OMX_IN OMX_PTR                   appData,
2428                                     OMX_IN OMX_U32                   bytes,
2429                                     OMX_IN OMX_U8*                   buffer)
2430 {
2431   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2432   if(m_state == OMX_StateInvalid)
2433   {
2434     DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n");
2435     return OMX_ErrorInvalidState;
2436   }
2437   if(port == PORT_INDEX_IN)
2438   {
2439     eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2440   }
2441   else if(port == PORT_INDEX_OUT)
2442   {
2443     eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2444   }
2445   else
2446   {
2447     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
2448     eRet = OMX_ErrorBadPortIndex;
2449   }
2450 
2451   if(eRet == OMX_ErrorNone)
2452   {
2453     if(allocate_done())
2454     {
2455       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2456       {
2457         // Send the callback now
2458         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
2459         post_event(OMX_CommandStateSet,OMX_StateIdle,
2460                    OMX_COMPONENT_GENERATE_EVENT);
2461       }
2462     }
2463     if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
2464     {
2465       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
2466       {
2467         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
2468         post_event(OMX_CommandPortEnable,
2469                    PORT_INDEX_IN,
2470                    OMX_COMPONENT_GENERATE_EVENT);
2471       }
2472 
2473     }
2474     else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
2475     {
2476       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
2477       {
2478         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2479         post_event(OMX_CommandPortEnable,
2480                    PORT_INDEX_OUT,
2481                    OMX_COMPONENT_GENERATE_EVENT);
2482         m_event_port_settings_sent = false;
2483       }
2484     }
2485   }
2486   return eRet;
2487 }
2488 
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)2489 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
2490 {
2491   unsigned int index = 0;
2492   OMX_U8 *temp_buff ;
2493 
2494   if(bufferHdr == NULL || m_inp_mem_ptr == NULL)
2495   {
2496     DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
2497       bufferHdr, m_inp_mem_ptr);
2498     return OMX_ErrorBadParameter;
2499   }
2500 
2501   index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
2502 #ifdef _ANDROID_ICS_
2503   if(meta_mode_enable)
2504   {
2505     if(index < m_sInPortDef.nBufferCountActual)
2506     {
2507       memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
2508       memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
2509     }
2510     if(!mUseProxyColorFormat)
2511       return OMX_ErrorNone;
2512     else {
2513       c2d_conv.close();
2514       opaque_buffer_hdr[index] = NULL;
2515     }
2516   }
2517 #endif
2518   if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
2519      dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
2520   {
2521     DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf");
2522   }
2523 
2524   if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem)
2525   {
2526     if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false)
2527     {
2528       DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case");
2529       munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
2530       close (m_pInput_pmem[index].fd);
2531 #ifdef USE_ION
2532       free_ion_memory(&m_pInput_ion[index]);
2533 #endif
2534       m_pInput_pmem[index].fd = -1;
2535     }
2536     else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
2537       m_use_input_pmem == OMX_FALSE))
2538     {
2539       DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case");
2540       if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
2541       {
2542         DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
2543       }
2544       munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
2545       close (m_pInput_pmem[index].fd);
2546 #ifdef USE_ION
2547       free_ion_memory(&m_pInput_ion[index]);
2548 #endif
2549       m_pInput_pmem[index].fd = -1;
2550     }
2551     else
2552     {
2553       DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
2554     }
2555   }
2556   return OMX_ErrorNone;
2557 }
2558 
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)2559 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
2560 {
2561   unsigned int index = 0;
2562   OMX_U8 *temp_buff ;
2563 
2564   if(bufferHdr == NULL || m_out_mem_ptr == NULL)
2565   {
2566     DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
2567       bufferHdr, m_out_mem_ptr);
2568     return OMX_ErrorBadParameter;
2569   }
2570   index = bufferHdr - m_out_mem_ptr;
2571 
2572   if(index < m_sOutPortDef.nBufferCountActual &&
2573      dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
2574   {
2575     DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
2576   }
2577 
2578   if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem)
2579   {
2580     if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false )
2581     {
2582       DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case");
2583       if(!secure_session)
2584         munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
2585       close (m_pOutput_pmem[index].fd);
2586 #ifdef USE_ION
2587       free_ion_memory(&m_pOutput_ion[index]);
2588 #endif
2589       m_pOutput_pmem[index].fd = -1;
2590     }
2591     else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
2592       && m_use_output_pmem == OMX_FALSE))
2593     {
2594       DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case");
2595       if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
2596       {
2597         DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
2598       }
2599       munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
2600       close (m_pOutput_pmem[index].fd);
2601 #ifdef USE_ION
2602       free_ion_memory(&m_pOutput_ion[index]);
2603 #endif
2604       m_pOutput_pmem[index].fd = -1;
2605     }
2606     else
2607     {
2608       DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
2609     }
2610   }
2611   return OMX_ErrorNone;
2612 }
2613 #ifdef _ANDROID_ICS_
allocate_input_meta_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_PTR appData,OMX_U32 bytes)2614 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
2615                     OMX_HANDLETYPE       hComp,
2616                     OMX_BUFFERHEADERTYPE **bufferHdr,
2617                     OMX_PTR              appData,
2618                     OMX_U32              bytes)
2619 {
2620   unsigned index = 0;
2621   if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type))
2622   {
2623     DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d",
2624                      bufferHdr,bytes);
2625     return OMX_ErrorBadParameter;
2626   }
2627   if(!m_inp_mem_ptr && !mUseProxyColorFormat)
2628     m_inp_mem_ptr = meta_buffer_hdr;
2629   for(index = 0;((index < m_sInPortDef.nBufferCountActual) &&
2630       meta_buffer_hdr[index].pBuffer); index++);
2631   if(index == m_sInPortDef.nBufferCountActual)
2632   {
2633     DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
2634     return OMX_ErrorBadParameter;
2635   }
2636   if(mUseProxyColorFormat){
2637     if(opaque_buffer_hdr[index]){
2638       DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
2639       return OMX_ErrorBadParameter;
2640     }
2641     if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
2642        PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
2643       DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
2644       return OMX_ErrorBadParameter;
2645     }
2646   }
2647   BITMASK_SET(&m_inp_bm_count,index);
2648   *bufferHdr = &meta_buffer_hdr[index];
2649   memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
2650   meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
2651   meta_buffer_hdr[index].nAllocLen = bytes;
2652   meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
2653   meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
2654   meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
2655   meta_buffer_hdr[index].pAppPrivate = appData;
2656   if(mUseProxyColorFormat) {
2657     m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0);
2658     DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
2659   }
2660   return OMX_ErrorNone;
2661 }
2662 #endif
2663 /* ======================================================================
2664 FUNCTION
2665   omx_venc::AllocateInputBuffer
2666 
2667 DESCRIPTION
2668   Helper function for allocate buffer in the input pin
2669 
2670 PARAMETERS
2671   None.
2672 
2673 RETURN VALUE
2674   true/false
2675 
2676 ========================================================================== */
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)2677 OMX_ERRORTYPE  omx_video::allocate_input_buffer(
2678                                                OMX_IN OMX_HANDLETYPE            hComp,
2679                                                OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2680                                                OMX_IN OMX_U32                   port,
2681                                                OMX_IN OMX_PTR                   appData,
2682                                                OMX_IN OMX_U32                   bytes)
2683 {
2684 
2685   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2686   unsigned   i = 0;
2687 
2688   DEBUG_PRINT_HIGH("\n allocate_input_buffer()::");
2689   if(bytes != m_sInPortDef.nBufferSize || secure_session)
2690   {
2691     DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n",
2692       bytes, m_sInPortDef.nBufferSize);
2693     return OMX_ErrorBadParameter;
2694   }
2695 
2696   if(!m_inp_mem_ptr)
2697   {
2698     DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
2699         m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual);
2700     m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
2701                     calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
2702     if(m_inp_mem_ptr == NULL)
2703     {
2704       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
2705       return OMX_ErrorInsufficientResources;
2706     }
2707 
2708     m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
2709 
2710     if(m_pInput_pmem == NULL)
2711     {
2712       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
2713       return OMX_ErrorInsufficientResources;
2714     }
2715 #ifdef USE_ION
2716     m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
2717     if(m_pInput_ion == NULL)
2718     {
2719       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
2720       return OMX_ErrorInsufficientResources;
2721     }
2722 #endif
2723     for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2724     {
2725       m_pInput_pmem[i].fd = -1;
2726 #ifdef USE_ION
2727       m_pInput_ion[i].ion_device_fd =-1;
2728       m_pInput_ion[i].fd_ion_data.fd =-1;
2729       m_pInput_ion[i].ion_alloc_data.handle=NULL;
2730 #endif
2731     }
2732   }
2733 
2734   for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2735   {
2736     if(BITMASK_ABSENT(&m_inp_bm_count,i))
2737     {
2738       break;
2739     }
2740   }
2741   if(i < m_sInPortDef.nBufferCountActual)
2742   {
2743 
2744     *bufferHdr = (m_inp_mem_ptr + i);
2745     (*bufferHdr)->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
2746     (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
2747     (*bufferHdr)->nAllocLen         = m_sInPortDef.nBufferSize;
2748     (*bufferHdr)->pAppPrivate       = appData;
2749     (*bufferHdr)->nInputPortIndex   = PORT_INDEX_IN;
2750 
2751 #ifdef USE_ION
2752     m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
2753                                     &m_pInput_ion[i].ion_alloc_data,
2754                                     &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2755     if(m_pInput_ion[i].ion_device_fd < 0) {
2756       DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2757       return OMX_ErrorInsufficientResources;
2758     }
2759 
2760     m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
2761 #else
2762     m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2763 
2764     if(m_pInput_pmem[i].fd == 0)
2765     {
2766       m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2767     }
2768 
2769     if(m_pInput_pmem[i].fd < 0)
2770     {
2771       DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n");
2772       return OMX_ErrorInsufficientResources;
2773     }
2774 #endif
2775     m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2776     m_pInput_pmem[i].offset = 0;
2777 
2778     m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
2779                                                     MAP_SHARED,m_pInput_pmem[i].fd,0);
2780     if(m_pInput_pmem[i].buffer == MAP_FAILED)
2781     {
2782       DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno);
2783       close(m_pInput_pmem[i].fd);
2784 #ifdef USE_ION
2785       free_ion_memory(&m_pInput_ion[i]);
2786 #endif
2787       return OMX_ErrorInsufficientResources;
2788     }
2789 
2790     (*bufferHdr)->pBuffer           = (OMX_U8 *)m_pInput_pmem[i].buffer;
2791     DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
2792     BITMASK_SET(&m_inp_bm_count,i);
2793     //here change the I/P param here from buf_adr to pmem
2794     if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true))
2795     {
2796       DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n");
2797       return OMX_ErrorInsufficientResources;
2798     }
2799   }
2800   else
2801   {
2802     DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call"
2803                       "for index [%d]\n", i);
2804     eRet = OMX_ErrorInsufficientResources;
2805   }
2806 
2807   return eRet;
2808 }
2809 
2810 
2811 /* ======================================================================
2812 FUNCTION
2813   omx_venc::AllocateOutputBuffer
2814 
2815 DESCRIPTION
2816   Helper fn for AllocateBuffer in the output pin
2817 
2818 PARAMETERS
2819   <TBD>.
2820 
2821 RETURN VALUE
2822   OMX Error None if everything went well.
2823 
2824 ========================================================================== */
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)2825 OMX_ERRORTYPE  omx_video::allocate_output_buffer(
2826                                                 OMX_IN OMX_HANDLETYPE            hComp,
2827                                                 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2828                                                 OMX_IN OMX_U32                   port,
2829                                                 OMX_IN OMX_PTR                   appData,
2830                                                 OMX_IN OMX_U32                   bytes)
2831 {
2832   OMX_ERRORTYPE eRet = OMX_ErrorNone;
2833   OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
2834   unsigned                         i= 0; // Temporary counter
2835 
2836   DEBUG_PRINT_HIGH("\n allocate_output_buffer()::");
2837   if(!m_out_mem_ptr)
2838   {
2839     int nBufHdrSize        = 0;
2840     DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
2841         m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual);
2842     nBufHdrSize        = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
2843 
2844     /*
2845      * Memory for output side involves the following:
2846      * 1. Array of Buffer Headers
2847      * 2. Bitmask array to hold the buffer allocation details
2848      * In order to minimize the memory management entire allocation
2849      * is done in one step.
2850      */
2851     m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
2852 
2853 #ifdef USE_ION
2854     m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
2855     if(m_pOutput_ion == NULL)
2856     {
2857       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
2858       return OMX_ErrorInsufficientResources;
2859     }
2860 #endif
2861     m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
2862     if(m_pOutput_pmem == NULL)
2863     {
2864       DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
2865       return OMX_ErrorInsufficientResources;
2866     }
2867     if(m_out_mem_ptr && m_pOutput_pmem)
2868     {
2869       bufHdr          =  m_out_mem_ptr;
2870 
2871       for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
2872       {
2873         bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
2874         bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
2875         // Set the values when we determine the right HxW param
2876         bufHdr->nAllocLen          = bytes;
2877         bufHdr->nFilledLen         = 0;
2878         bufHdr->pAppPrivate        = appData;
2879         bufHdr->nOutputPortIndex   = PORT_INDEX_OUT;
2880         bufHdr->pBuffer            = NULL;
2881         bufHdr++;
2882         m_pOutput_pmem[i].fd = -1;
2883 #ifdef USE_ION
2884         m_pOutput_ion[i].ion_device_fd =-1;
2885         m_pOutput_ion[i].fd_ion_data.fd=-1;
2886         m_pOutput_ion[i].ion_alloc_data.handle =NULL;
2887 #endif
2888       }
2889     }
2890     else
2891     {
2892       DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
2893       eRet = OMX_ErrorInsufficientResources;
2894     }
2895   }
2896 
2897   DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual);
2898   for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
2899   {
2900     if(BITMASK_ABSENT(&m_out_bm_count,i))
2901     {
2902       DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
2903       break;
2904     }
2905   }
2906   if(eRet == OMX_ErrorNone)
2907   {
2908     if(i < m_sOutPortDef.nBufferCountActual)
2909     {
2910 #ifdef USE_ION
2911       m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
2912                                        &m_pOutput_ion[i].ion_alloc_data,
2913                                        &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2914       if(m_pOutput_ion[i].ion_device_fd < 0) {
2915         DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2916         return OMX_ErrorInsufficientResources;
2917       }
2918       m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
2919 #else
2920       m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2921       if(m_pOutput_pmem[i].fd == 0)
2922       {
2923         m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2924       }
2925 
2926       if(m_pOutput_pmem[i].fd < 0)
2927       {
2928         DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed");
2929         return OMX_ErrorInsufficientResources;
2930       }
2931 #endif
2932       m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2933       m_pOutput_pmem[i].offset = 0;
2934       if(!secure_session) {
2935           m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
2936                   MAP_SHARED,m_pOutput_pmem[i].fd,0);
2937           if(m_pOutput_pmem[i].buffer == MAP_FAILED)
2938           {
2939               DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer");
2940               close (m_pOutput_pmem[i].fd);
2941 #ifdef USE_ION
2942               free_ion_memory(&m_pOutput_ion[i]);
2943 #endif
2944               return OMX_ErrorInsufficientResources;
2945           }
2946       }
2947 
2948       *bufferHdr = (m_out_mem_ptr + i );
2949       if(!secure_session)
2950         (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
2951       else {
2952         m_pOutput_pmem[i].buffer = (OMX_U8 *)(i + 12345);
2953         (*bufferHdr)->pBuffer = (OMX_U8 *)(i + 12345);
2954       }
2955       (*bufferHdr)->pAppPrivate = appData;
2956 
2957       BITMASK_SET(&m_out_bm_count,i);
2958 
2959       if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
2960       {
2961         DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf");
2962         return OMX_ErrorInsufficientResources;
2963       }
2964     }
2965     else
2966     {
2967       DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call"
2968                         "for index [%d]\n", i);
2969     }
2970   }
2971 
2972   return eRet;
2973 }
2974 
2975 
2976 // AllocateBuffer  -- API Call
2977 /* ======================================================================
2978 FUNCTION
2979   omx_video::AllocateBuffer
2980 
2981 DESCRIPTION
2982   Returns zero if all the buffers released..
2983 
2984 PARAMETERS
2985   None.
2986 
2987 RETURN VALUE
2988   true/false
2989 
2990 ========================================================================== */
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)2991 OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
2992                                           OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2993                                           OMX_IN OMX_U32                        port,
2994                                           OMX_IN OMX_PTR                     appData,
2995                                           OMX_IN OMX_U32                       bytes)
2996 {
2997 
2998   OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
2999 
3000   DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port);
3001   if(m_state == OMX_StateInvalid)
3002   {
3003     DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n");
3004     return OMX_ErrorInvalidState;
3005   }
3006 
3007   // What if the client calls again.
3008   if(port == PORT_INDEX_IN)
3009   {
3010 #ifdef _ANDROID_ICS_
3011     if(meta_mode_enable)
3012       eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
3013     else
3014 #endif
3015     eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3016   }
3017   else if(port == PORT_INDEX_OUT)
3018   {
3019     eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3020   }
3021   else
3022   {
3023     DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
3024     eRet = OMX_ErrorBadPortIndex;
3025   }
3026   DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
3027   if(eRet == OMX_ErrorNone)
3028   {
3029     if(allocate_done())
3030     {
3031       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3032       {
3033         // Send the callback now
3034         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3035         post_event(OMX_CommandStateSet,OMX_StateIdle,
3036                    OMX_COMPONENT_GENERATE_EVENT);
3037       }
3038     }
3039     if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
3040     {
3041       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
3042       {
3043         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3044         post_event(OMX_CommandPortEnable,
3045                    PORT_INDEX_IN,
3046                    OMX_COMPONENT_GENERATE_EVENT);
3047       }
3048     }
3049     if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
3050     {
3051       if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
3052       {
3053         BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3054         post_event(OMX_CommandPortEnable,
3055                    PORT_INDEX_OUT,
3056                    OMX_COMPONENT_GENERATE_EVENT);
3057         m_event_port_settings_sent = false;
3058       }
3059     }
3060   }
3061   DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
3062   return eRet;
3063 }
3064 
3065 
3066 // Free Buffer - API call
3067 /* ======================================================================
3068 FUNCTION
3069   omx_video::FreeBuffer
3070 
3071 DESCRIPTION
3072 
3073 PARAMETERS
3074   None.
3075 
3076 RETURN VALUE
3077   true/false
3078 
3079 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3080 OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
3081                                       OMX_IN OMX_U32                 port,
3082                                       OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3083 {
3084   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3085   unsigned int nPortIndex;
3086 
3087   DEBUG_PRINT_LOW("In for decoder free_buffer \n");
3088 
3089   if(m_state == OMX_StateIdle &&
3090      (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3091   {
3092     DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
3093   }
3094   else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
3095           (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT))
3096   {
3097     DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
3098   }
3099   else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
3100   {
3101     DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n");
3102     post_event(OMX_EventError,
3103                OMX_ErrorPortUnpopulated,
3104                OMX_COMPONENT_GENERATE_EVENT);
3105 
3106     return eRet;
3107   }
3108   else
3109   {
3110     DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n");
3111     post_event(OMX_EventError,
3112                OMX_ErrorPortUnpopulated,
3113                OMX_COMPONENT_GENERATE_EVENT);
3114   }
3115 
3116   if(port == PORT_INDEX_IN)
3117   {
3118     // check if the buffer is valid
3119     nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
3120 
3121     DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n",
3122                     nPortIndex, m_sInPortDef.nBufferCountActual);
3123     if(nPortIndex < m_sInPortDef.nBufferCountActual)
3124     {
3125       // Clear the bit associated with it.
3126       BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
3127       free_input_buffer (buffer);
3128       m_sInPortDef.bPopulated = OMX_FALSE;
3129 
3130       /*Free the Buffer Header*/
3131       if(release_input_done()
3132 #ifdef _ANDROID_ICS_
3133          && !meta_mode_enable
3134 #endif
3135          )
3136       {
3137         input_use_buffer = false;
3138         if(m_inp_mem_ptr)
3139         {
3140           DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n");
3141           free (m_inp_mem_ptr);
3142           m_inp_mem_ptr = NULL;
3143         }
3144         if(m_pInput_pmem)
3145         {
3146           DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n");
3147           free(m_pInput_pmem);
3148           m_pInput_pmem = NULL;
3149         }
3150 #ifdef USE_ION
3151         if(m_pInput_ion)
3152         {
3153           DEBUG_PRINT_LOW("Freeing m_pInput_ion\n");
3154           free(m_pInput_ion);
3155           m_pInput_ion = NULL;
3156         }
3157 #endif
3158       }
3159     }
3160     else
3161     {
3162       DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n");
3163       eRet = OMX_ErrorBadPortIndex;
3164     }
3165 
3166     if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3167        && release_input_done())
3168     {
3169       DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
3170       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3171       post_event(OMX_CommandPortDisable,
3172                  PORT_INDEX_IN,
3173                  OMX_COMPONENT_GENERATE_EVENT);
3174     }
3175   }
3176   else if(port == PORT_INDEX_OUT)
3177   {
3178     // check if the buffer is valid
3179     nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3180 
3181     DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n",
3182                     nPortIndex, m_sOutPortDef.nBufferCountActual);
3183     if(nPortIndex < m_sOutPortDef.nBufferCountActual)
3184     {
3185       // Clear the bit associated with it.
3186       BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
3187       m_sOutPortDef.bPopulated = OMX_FALSE;
3188       free_output_buffer (buffer);
3189 
3190       if(release_output_done())
3191       {
3192         output_use_buffer = false;
3193         if(m_out_mem_ptr)
3194         {
3195           DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n");
3196           free (m_out_mem_ptr);
3197           m_out_mem_ptr = NULL;
3198         }
3199         if(m_pOutput_pmem)
3200         {
3201           DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n");
3202           free(m_pOutput_pmem);
3203           m_pOutput_pmem = NULL;
3204         }
3205 #ifdef USE_ION
3206         if(m_pOutput_ion)
3207         {
3208           DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n");
3209           free(m_pOutput_ion);
3210           m_pOutput_ion = NULL;
3211         }
3212 #endif
3213       }
3214     }
3215     else
3216     {
3217       DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n");
3218       eRet = OMX_ErrorBadPortIndex;
3219     }
3220     if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3221        && release_output_done() )
3222     {
3223       DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
3224 
3225       DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
3226       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3227       post_event(OMX_CommandPortDisable,
3228                  PORT_INDEX_OUT,
3229                  OMX_COMPONENT_GENERATE_EVENT);
3230 
3231     }
3232   }
3233   else
3234   {
3235     eRet = OMX_ErrorBadPortIndex;
3236   }
3237   if((eRet == OMX_ErrorNone) &&
3238      (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3239   {
3240     if(release_done())
3241     {
3242       if(dev_stop() != 0)
3243       {
3244         DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n");
3245         eRet = OMX_ErrorHardware;
3246       }
3247       // Send the callback now
3248       BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3249       post_event(OMX_CommandStateSet, OMX_StateLoaded,
3250                  OMX_COMPONENT_GENERATE_EVENT);
3251     }
3252   }
3253 
3254   return eRet;
3255 }
3256 
3257 
3258 /* ======================================================================
3259 FUNCTION
3260   omx_video::EmptyThisBuffer
3261 
3262 DESCRIPTION
3263   This routine is used to push the encoded video frames to
3264   the video decoder.
3265 
3266 PARAMETERS
3267   None.
3268 
3269 RETURN VALUE
3270   OMX Error None if everything went successful.
3271 
3272 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3273 OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
3274                                             OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3275 {
3276   OMX_ERRORTYPE ret1 = OMX_ErrorNone;
3277   unsigned int nBufferIndex ;
3278 
3279   DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer);
3280   if(m_state == OMX_StateInvalid)
3281   {
3282     DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n");
3283     return OMX_ErrorInvalidState;
3284   }
3285 
3286   if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
3287   {
3288     DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid");
3289     return OMX_ErrorBadParameter;
3290   }
3291 
3292   if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
3293   {
3294     DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid");
3295     return OMX_ErrorVersionMismatch;
3296   }
3297 
3298   if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN)
3299   {
3300     DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer");
3301     return OMX_ErrorBadPortIndex;
3302   }
3303   if(!m_sInPortDef.bEnabled)
3304   {
3305     DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled");
3306     return OMX_ErrorIncorrectStateOperation;
3307   }
3308 
3309   nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
3310 
3311   if(nBufferIndex > m_sInPortDef.nBufferCountActual )
3312   {
3313     DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex);
3314     return OMX_ErrorBadParameter;
3315   }
3316 
3317   m_etb_count++;
3318   DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
3319   post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id);
3320   return OMX_ErrorNone;
3321 }
3322 /* ======================================================================
3323 FUNCTION
3324   omx_video::empty_this_buffer_proxy
3325 
3326 DESCRIPTION
3327   This routine is used to push the encoded video frames to
3328   the video decoder.
3329 
3330 PARAMETERS
3331   None.
3332 
3333 RETURN VALUE
3334   OMX Error None if everything went successful.
3335 
3336 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3337 OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
3338                                                   OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3339 {
3340   OMX_U8 *pmem_data_buf = NULL;
3341   int push_cnt = 0;
3342   unsigned nBufIndex = 0,nBufIndex_meta = 0;
3343   OMX_ERRORTYPE ret = OMX_ErrorNone;
3344 
3345   DEBUG_PRINT_LOW("\n ETBProxy: buffer[%p]\n", buffer);
3346 
3347   if(buffer == NULL)
3348   {
3349     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer);
3350     return OMX_ErrorBadParameter;
3351   }
3352 
3353   nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
3354   nBufIndex_meta = buffer - meta_buffer_hdr;
3355   if(nBufIndex >= m_sInPortDef.nBufferCountActual &&
3356      nBufIndex_meta >= m_sInPortDef.nBufferCountActual)
3357   {
3358     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex);
3359     return OMX_ErrorBadParameter;
3360   }
3361 
3362   pending_input_buffers++;
3363   if(input_flush_progress == true)
3364   {
3365     post_event ((unsigned int)buffer,0,
3366                 OMX_COMPONENT_GENERATE_EBD);
3367     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress");
3368     return OMX_ErrorNone;
3369   }
3370 #ifdef _ANDROID_ICS_
3371   if(meta_mode_enable && !mUseProxyColorFormat)
3372   {
3373     encoder_media_buffer_type *media_buffer;
3374     bool met_error = false;
3375     media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer;
3376     if(media_buffer)
3377     {
3378       if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource &&
3379           media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
3380           met_error = true;
3381       } else {
3382         if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
3383         {
3384           if(media_buffer->meta_handle == NULL) {
3385             met_error = true;
3386           }
3387           else if((media_buffer->meta_handle->numFds != 1 &&
3388                    media_buffer->meta_handle->numInts != 2))
3389           {
3390             met_error = true;
3391           }
3392         }
3393       }
3394     } else {
3395       met_error = true;
3396     }
3397     if(met_error)
3398     {
3399       DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call");
3400       post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3401       return OMX_ErrorBadParameter;
3402     }
3403 
3404     struct pmem Input_pmem_info;
3405     if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
3406     {
3407       Input_pmem_info.buffer = media_buffer;
3408       Input_pmem_info.fd = media_buffer->meta_handle->data[0];
3409       Input_pmem_info.offset = media_buffer->meta_handle->data[1];
3410       Input_pmem_info.size = media_buffer->meta_handle->data[2];
3411       DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
3412                         Input_pmem_info.offset,
3413                         Input_pmem_info.size);
3414 
3415     } else {
3416       private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
3417       if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3418         DEBUG_PRINT_ERROR("\n Incorrect pixel format");
3419         post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3420         return OMX_ErrorBadParameter;
3421       }
3422       Input_pmem_info.buffer = media_buffer;
3423       Input_pmem_info.fd = handle->fd;
3424       Input_pmem_info.offset = 0;
3425       Input_pmem_info.size = handle->size;
3426     }
3427     if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
3428       DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
3429       post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3430       return OMX_ErrorBadParameter;
3431     }
3432   }
3433   else if(input_use_buffer && !m_use_input_pmem)
3434 #else
3435   if(input_use_buffer && !m_use_input_pmem)
3436 #endif
3437   {
3438     DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data");
3439     pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
3440 
3441     memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
3442             buffer->nFilledLen);
3443     DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
3444   } else if (m_sInPortDef.format.video.eColorFormat ==
3445       OMX_COLOR_FormatYUV420SemiPlanar && !mUseProxyColorFormat) {
3446       //For the case where YUV420SP buffers are qeueued to component
3447       //by sources other than camera (Apps via MediaCodec), alignment
3448       //of chroma-plane to 2K is necessary.
3449       //For RGB buffers, color-conversion takes care of such alignment
3450       OMX_U32 width = m_sInPortDef.format.video.nFrameWidth;
3451       OMX_U32 height = m_sInPortDef.format.video.nFrameHeight;
3452       OMX_U32 chromaOffset = width * height;
3453       if (IS_NOT_ALIGNED(chromaOffset, SZ_2K)) {
3454           OMX_U32 chromaSize = (width * height)/2;
3455           chromaOffset = ALIGN(chromaOffset,SZ_2K);
3456           if (buffer->nAllocLen >= chromaOffset + chromaSize) {
3457               OMX_U8* buf = buffer->pBuffer;
3458               memmove(buf + chromaOffset, buf + (width*height), chromaSize);
3459           } else {
3460              DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3461                  Insufficient bufferLen=%u v/s Required=%u",
3462                  (width*height), chromaOffset, buffer->nAllocLen,
3463                  chromaOffset+chromaSize);
3464           }
3465       }
3466   }
3467 #ifdef _COPPER_
3468   if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true)
3469 #else
3470   if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
3471 #endif
3472   {
3473     DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed");
3474 #ifdef _ANDROID_ICS_
3475     omx_release_meta_buffer(buffer);
3476 #endif
3477     post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3478     /*Generate an async error and move to invalid state*/
3479     pending_input_buffers--;
3480     return OMX_ErrorBadParameter;
3481   }
3482 
3483   return ret;
3484 }
3485 
3486 /* ======================================================================
3487 FUNCTION
3488   omx_video::FillThisBuffer
3489 
3490 DESCRIPTION
3491   IL client uses this method to release the frame buffer
3492   after displaying them.
3493 
3494 PARAMETERS
3495   None.
3496 
3497 RETURN VALUE
3498   true/false
3499 
3500 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3501 OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
3502                                            OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3503 {
3504   DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer);
3505   if(m_state == OMX_StateInvalid)
3506   {
3507     DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n");
3508     return OMX_ErrorInvalidState;
3509   }
3510 
3511   if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
3512   {
3513     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n");
3514     return OMX_ErrorBadParameter;
3515   }
3516 
3517   if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
3518   {
3519     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n");
3520     return OMX_ErrorVersionMismatch;
3521   }
3522 
3523   if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT)
3524   {
3525     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n");
3526     return OMX_ErrorBadPortIndex;
3527   }
3528 
3529   if(!m_sOutPortDef.bEnabled)
3530   {
3531     DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n");
3532     return OMX_ErrorIncorrectStateOperation;
3533   }
3534 
3535   post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
3536   return OMX_ErrorNone;
3537 }
3538 
3539 /* ======================================================================
3540 FUNCTION
3541   omx_video::fill_this_buffer_proxy
3542 
3543 DESCRIPTION
3544   IL client uses this method to release the frame buffer
3545   after displaying them.
3546 
3547 PARAMETERS
3548   None.
3549 
3550 RETURN VALUE
3551   true/false
3552 
3553 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)3554 OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
3555                                                 OMX_IN OMX_HANDLETYPE        hComp,
3556                                                 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
3557 {
3558   OMX_U8 *pmem_data_buf = NULL;
3559   OMX_ERRORTYPE nRet = OMX_ErrorNone;
3560 
3561   DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer);
3562 
3563   if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) )
3564   {
3565     DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n");
3566     return OMX_ErrorBadParameter;
3567   }
3568 
3569   pending_output_buffers++;
3570   /*Return back the output buffer to client*/
3571   if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true)
3572   {
3573     DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress");
3574     post_event ((unsigned int)bufferAdd,0,
3575                 OMX_COMPONENT_GENERATE_FBD);
3576     return OMX_ErrorNone;
3577   }
3578 
3579   if(output_use_buffer && !m_use_output_pmem)
3580   {
3581     DEBUG_PRINT_LOW("\n Heap UseBuffer case");
3582     pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
3583   }
3584 
3585   if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true)
3586   {
3587     DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed");
3588     post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
3589     pending_output_buffers--;
3590     return OMX_ErrorBadParameter;
3591   }
3592 
3593   return OMX_ErrorNone;
3594 }
3595 
3596 /* ======================================================================
3597 FUNCTION
3598   omx_video::SetCallbacks
3599 
3600 DESCRIPTION
3601   Set the callbacks.
3602 
3603 PARAMETERS
3604   None.
3605 
3606 RETURN VALUE
3607   OMX Error None if everything successful.
3608 
3609 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)3610 OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
3611                                         OMX_IN OMX_CALLBACKTYPE* callbacks,
3612                                         OMX_IN OMX_PTR             appData)
3613 {
3614 
3615   m_pCallbacks       = *callbacks;
3616   DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
3617                m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
3618   m_app_data =    appData;
3619   return OMX_ErrorNotImplemented;
3620 }
3621 
3622 
3623 /* ======================================================================
3624 FUNCTION
3625   omx_venc::UseEGLImage
3626 
3627 DESCRIPTION
3628   OMX Use EGL Image method implementation <TBD>.
3629 
3630 PARAMETERS
3631   <TBD>.
3632 
3633 RETURN VALUE
3634   Not Implemented error.
3635 
3636 ========================================================================== */
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)3637 OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
3638                                         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3639                                         OMX_IN OMX_U32                        port,
3640                                         OMX_IN OMX_PTR                     appData,
3641                                         OMX_IN void*                      eglImage)
3642 {
3643   DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented \n");
3644   return OMX_ErrorNotImplemented;
3645 }
3646 
3647 /* ======================================================================
3648 FUNCTION
3649   omx_venc::ComponentRoleEnum
3650 
3651 DESCRIPTION
3652   OMX Component Role Enum method implementation.
3653 
3654 PARAMETERS
3655   <TBD>.
3656 
3657 RETURN VALUE
3658   OMX Error None if everything is successful.
3659 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)3660 OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
3661                                               OMX_OUT OMX_U8*        role,
3662                                               OMX_IN OMX_U32        index)
3663 {
3664   OMX_ERRORTYPE eRet = OMX_ErrorNone;
3665   if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3666   {
3667     if((0 == index) && role)
3668     {
3669       strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3670       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3671     }
3672     else
3673     {
3674       eRet = OMX_ErrorNoMore;
3675     }
3676   }
3677   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3678   {
3679     if((0 == index) && role)
3680     {
3681       strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3682       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3683     }
3684     else
3685     {
3686       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3687       eRet = OMX_ErrorNoMore;
3688     }
3689   }
3690   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3691   {
3692     if((0 == index) && role)
3693     {
3694       strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3695       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3696     }
3697     else
3698     {
3699       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3700       eRet = OMX_ErrorNoMore;
3701     }
3702   }
3703   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3704   {
3705     if((0 == index) && role)
3706     {
3707       strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3708       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3709     }
3710     else
3711     {
3712       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3713       eRet = OMX_ErrorNoMore;
3714     }
3715   }
3716   if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3717   {
3718     if((0 == index) && role)
3719     {
3720       strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3721       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3722     }
3723     else
3724     {
3725       eRet = OMX_ErrorNoMore;
3726     }
3727   }
3728   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE))
3729   {
3730     if((0 == index) && role)
3731     {
3732       strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
3733       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3734     }
3735     else
3736     {
3737       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3738       eRet = OMX_ErrorNoMore;
3739     }
3740   }
3741   else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE))
3742   {
3743     if((0 == index) && role)
3744     {
3745       strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
3746       DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3747     }
3748     else
3749     {
3750       DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3751       eRet = OMX_ErrorNoMore;
3752     }
3753   }
3754   else
3755   {
3756     DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n");
3757     eRet = OMX_ErrorInvalidComponentName;
3758   }
3759   return eRet;
3760 }
3761 
3762 
3763 
3764 
3765 /* ======================================================================
3766 FUNCTION
3767   omx_venc::AllocateDone
3768 
3769 DESCRIPTION
3770   Checks if entire buffer pool is allocated by IL Client or not.
3771   Need this to move to IDLE state.
3772 
3773 PARAMETERS
3774   None.
3775 
3776 RETURN VALUE
3777   true/false.
3778 
3779 ========================================================================== */
allocate_done(void)3780 bool omx_video::allocate_done(void)
3781 {
3782   bool bRet = false;
3783   bool bRet_In = false;
3784   bool bRet_Out = false;
3785 
3786   bRet_In = allocate_input_done();
3787   bRet_Out = allocate_output_done();
3788 
3789   if(bRet_In && bRet_Out)
3790   {
3791     bRet = true;
3792   }
3793 
3794   return bRet;
3795 }
3796 /* ======================================================================
3797 FUNCTION
3798   omx_venc::AllocateInputDone
3799 
3800 DESCRIPTION
3801   Checks if I/P buffer pool is allocated by IL Client or not.
3802 
3803 PARAMETERS
3804   None.
3805 
3806 RETURN VALUE
3807   true/false.
3808 
3809 ========================================================================== */
allocate_input_done(void)3810 bool omx_video::allocate_input_done(void)
3811 {
3812   bool bRet = false;
3813   unsigned i=0;
3814 
3815   if(m_inp_mem_ptr == NULL)
3816   {
3817     return bRet;
3818   }
3819   if(m_inp_mem_ptr )
3820   {
3821     for(;i<m_sInPortDef.nBufferCountActual;i++)
3822     {
3823       if(BITMASK_ABSENT(&m_inp_bm_count,i))
3824       {
3825         break;
3826       }
3827     }
3828   }
3829   if(i==m_sInPortDef.nBufferCountActual)
3830   {
3831     bRet = true;
3832   }
3833   if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled)
3834   {
3835     m_sInPortDef.bPopulated = OMX_TRUE;
3836   }
3837   return bRet;
3838 }
3839 /* ======================================================================
3840 FUNCTION
3841   omx_venc::AllocateOutputDone
3842 
3843 DESCRIPTION
3844   Checks if entire O/P buffer pool is allocated by IL Client or not.
3845 
3846 PARAMETERS
3847   None.
3848 
3849 RETURN VALUE
3850   true/false.
3851 
3852 ========================================================================== */
allocate_output_done(void)3853 bool omx_video::allocate_output_done(void)
3854 {
3855   bool bRet = false;
3856   unsigned j=0;
3857 
3858   if(m_out_mem_ptr == NULL)
3859   {
3860     return bRet;
3861   }
3862 
3863   if(m_out_mem_ptr )
3864   {
3865     for(;j<m_sOutPortDef.nBufferCountActual;j++)
3866     {
3867       if(BITMASK_ABSENT(&m_out_bm_count,j))
3868       {
3869         break;
3870       }
3871     }
3872   }
3873 
3874   if(j==m_sOutPortDef.nBufferCountActual)
3875   {
3876     bRet = true;
3877   }
3878 
3879   if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled)
3880   {
3881     m_sOutPortDef.bPopulated = OMX_TRUE;
3882   }
3883   return bRet;
3884 }
3885 
3886 /* ======================================================================
3887 FUNCTION
3888   omx_venc::ReleaseDone
3889 
3890 DESCRIPTION
3891   Checks if IL client has released all the buffers.
3892 
3893 PARAMETERS
3894   None.
3895 
3896 RETURN VALUE
3897   true/false
3898 
3899 ========================================================================== */
release_done(void)3900 bool omx_video::release_done(void)
3901 {
3902   bool bRet = false;
3903   DEBUG_PRINT_LOW("Inside release_done()\n");
3904   if(release_input_done())
3905   {
3906     if(release_output_done())
3907     {
3908       bRet = true;
3909     }
3910   }
3911   return bRet;
3912 }
3913 
3914 
3915 /* ======================================================================
3916 FUNCTION
3917   omx_venc::ReleaseOutputDone
3918 
3919 DESCRIPTION
3920   Checks if IL client has released all the buffers.
3921 
3922 PARAMETERS
3923   None.
3924 
3925 RETURN VALUE
3926   true/false
3927 
3928 ========================================================================== */
release_output_done(void)3929 bool omx_video::release_output_done(void)
3930 {
3931   bool bRet = false;
3932   unsigned i=0,j=0;
3933 
3934   DEBUG_PRINT_LOW("Inside release_output_done()\n");
3935   if(m_out_mem_ptr)
3936   {
3937     for(;j<m_sOutPortDef.nBufferCountActual;j++)
3938     {
3939       if(BITMASK_PRESENT(&m_out_bm_count,j))
3940       {
3941         break;
3942       }
3943     }
3944     if(j==m_sOutPortDef.nBufferCountActual)
3945     {
3946       bRet = true;
3947     }
3948   }
3949   else
3950   {
3951     bRet = true;
3952   }
3953   return bRet;
3954 }
3955 /* ======================================================================
3956 FUNCTION
3957   omx_venc::ReleaseInputDone
3958 
3959 DESCRIPTION
3960   Checks if IL client has released all the buffers.
3961 
3962 PARAMETERS
3963   None.
3964 
3965 RETURN VALUE
3966   true/false
3967 
3968 ========================================================================== */
release_input_done(void)3969 bool omx_video::release_input_done(void)
3970 {
3971   bool bRet = false;
3972   unsigned i=0,j=0;
3973 
3974   DEBUG_PRINT_LOW("Inside release_input_done()\n");
3975   if(m_inp_mem_ptr)
3976   {
3977     for(;j<m_sInPortDef.nBufferCountActual;j++)
3978     {
3979       if( BITMASK_PRESENT(&m_inp_bm_count,j))
3980       {
3981         break;
3982       }
3983     }
3984     if(j==m_sInPortDef.nBufferCountActual)
3985     {
3986       bRet = true;
3987     }
3988   }
3989   else
3990   {
3991     bRet = true;
3992   }
3993   return bRet;
3994 }
3995 
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)3996 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
3997                                           OMX_BUFFERHEADERTYPE * buffer)
3998 {
3999   DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %d",
4000      buffer->pBuffer, buffer->nFlags,buffer->nFilledLen);
4001   if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual))
4002   {
4003     return OMX_ErrorBadParameter;
4004   }
4005 
4006   pending_output_buffers--;
4007   if(!secure_session)
4008   {
4009     extra_data_handle.create_extra_data(buffer);
4010   }
4011 
4012   if (!secure_session && m_sDebugSliceinfo) {
4013     if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
4014        DEBUG_PRINT_HIGH("parsing extradata");
4015        extra_data_handle.parse_extra_data(buffer);
4016     }
4017   }
4018   /* For use buffer we need to copy the data */
4019   if(m_pCallbacks.FillBufferDone)
4020   {
4021     if(buffer->nFilledLen > 0)
4022     {
4023       m_fbd_count++;
4024 
4025 #ifdef OUTPUT_BUFFER_LOG
4026       if(outputBufferFile1)
4027       {
4028         fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1);
4029       }
4030 #endif
4031     }
4032     m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4033   }
4034   else
4035   {
4036     return OMX_ErrorBadParameter;
4037   }
4038   return OMX_ErrorNone;
4039 }
4040 
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4041 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
4042                                            OMX_BUFFERHEADERTYPE* buffer)
4043 {
4044   int buffer_index  = -1;
4045   int buffer_index_meta = -1;
4046 
4047   buffer_index = (buffer - m_inp_mem_ptr);
4048   buffer_index_meta = (buffer - meta_buffer_hdr);
4049   DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer);
4050   if(buffer == NULL ||
4051      ((buffer_index > m_sInPortDef.nBufferCountActual) &&
4052       (buffer_index_meta > m_sInPortDef.nBufferCountActual)))
4053   {
4054     DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer");
4055     return OMX_ErrorBadParameter;
4056   }
4057 
4058   pending_input_buffers--;
4059 
4060   if(mUseProxyColorFormat && (buffer_index < m_sInPortDef.nBufferCountActual)) {
4061     if(!pdest_frame) {
4062       pdest_frame = buffer;
4063       DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame);
4064       return push_input_buffer(hComp);
4065 
4066     } else {
4067       DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer);
4068       if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) {
4069         DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full");
4070         return OMX_ErrorBadParameter;
4071       }
4072     }
4073   } else if(m_pCallbacks.EmptyBufferDone) {
4074     m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4075   }
4076   return OMX_ErrorNone;
4077 }
4078 
complete_pending_buffer_done_cbs()4079 void omx_video::complete_pending_buffer_done_cbs()
4080 {
4081   unsigned p1;
4082   unsigned p2;
4083   unsigned ident;
4084   omx_cmd_queue tmp_q, pending_bd_q;
4085   pthread_mutex_lock(&m_lock);
4086   // pop all pending GENERATE FDB from ftb queue
4087   while (m_ftb_q.m_size)
4088   {
4089     m_ftb_q.pop_entry(&p1,&p2,&ident);
4090     if(ident == OMX_COMPONENT_GENERATE_FBD)
4091     {
4092       pending_bd_q.insert_entry(p1,p2,ident);
4093     }
4094     else
4095     {
4096       tmp_q.insert_entry(p1,p2,ident);
4097     }
4098   }
4099   //return all non GENERATE FDB to ftb queue
4100   while(tmp_q.m_size)
4101   {
4102     tmp_q.pop_entry(&p1,&p2,&ident);
4103     m_ftb_q.insert_entry(p1,p2,ident);
4104   }
4105   // pop all pending GENERATE EDB from etb queue
4106   while (m_etb_q.m_size)
4107   {
4108     m_etb_q.pop_entry(&p1,&p2,&ident);
4109     if(ident == OMX_COMPONENT_GENERATE_EBD)
4110     {
4111       pending_bd_q.insert_entry(p1,p2,ident);
4112     }
4113     else
4114     {
4115       tmp_q.insert_entry(p1,p2,ident);
4116     }
4117   }
4118   //return all non GENERATE FDB to etb queue
4119   while(tmp_q.m_size)
4120   {
4121     tmp_q.pop_entry(&p1,&p2,&ident);
4122     m_etb_q.insert_entry(p1,p2,ident);
4123   }
4124   pthread_mutex_unlock(&m_lock);
4125   // process all pending buffer dones
4126   while(pending_bd_q.m_size)
4127   {
4128     pending_bd_q.pop_entry(&p1,&p2,&ident);
4129     switch(ident)
4130     {
4131     case OMX_COMPONENT_GENERATE_EBD:
4132         if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
4133         {
4134           DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
4135           omx_report_error ();
4136         }
4137         break;
4138 
4139       case OMX_COMPONENT_GENERATE_FBD:
4140         if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
4141         {
4142           DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
4143           omx_report_error ();
4144         }
4145         break;
4146     }
4147   }
4148 }
4149 
4150 #ifdef MAX_RES_720P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4151 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4152 {
4153   OMX_ERRORTYPE eRet = OMX_ErrorNone;
4154   if(!profileLevelType)
4155     return OMX_ErrorBadParameter;
4156 
4157   if(profileLevelType->nPortIndex == 1) {
4158     if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4159     {
4160       if (profileLevelType->nProfileIndex == 0)
4161       {
4162         profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4163         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4164       }
4165       else if (profileLevelType->nProfileIndex == 1)
4166       {
4167         profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4168         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4169       }
4170       else if(profileLevelType->nProfileIndex == 2)
4171       {
4172         profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4173         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4174       }
4175       else
4176       {
4177         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4178             profileLevelType->nProfileIndex);
4179         eRet = OMX_ErrorNoMore;
4180       }
4181     }
4182     else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4183     {
4184       if (profileLevelType->nProfileIndex == 0)
4185       {
4186         profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4187         profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4188       }
4189       else
4190       {
4191         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4192         eRet = OMX_ErrorNoMore;
4193       }
4194     }
4195     else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4196     {
4197       if (profileLevelType->nProfileIndex == 0)
4198       {
4199         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4200         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4201       }
4202       else if(profileLevelType->nProfileIndex == 1)
4203       {
4204         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4205         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4206       }
4207       else
4208       {
4209         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4210         eRet = OMX_ErrorNoMore;
4211       }
4212     }
4213   }
4214   else
4215   {
4216     DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4217     eRet = OMX_ErrorBadPortIndex;
4218   }
4219   DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4220                     profileLevelType->eProfile,profileLevelType->eLevel);
4221   return eRet;
4222 }
4223 #endif
4224 
4225 #ifdef MAX_RES_1080P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4226 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4227 {
4228   OMX_ERRORTYPE eRet = OMX_ErrorNone;
4229   if(!profileLevelType)
4230     return OMX_ErrorBadParameter;
4231 
4232   if(profileLevelType->nPortIndex == 1) {
4233     if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4234     {
4235       if (profileLevelType->nProfileIndex == 0)
4236       {
4237         profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4238         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4239 
4240       }
4241       else if (profileLevelType->nProfileIndex == 1)
4242       {
4243         profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4244         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4245       }
4246       else if(profileLevelType->nProfileIndex == 2)
4247       {
4248         profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4249         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4250       }
4251       else
4252       {
4253         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4254             profileLevelType->nProfileIndex);
4255         eRet = OMX_ErrorNoMore;
4256       }
4257     }
4258     else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4259     {
4260       if (profileLevelType->nProfileIndex == 0)
4261       {
4262         profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4263         profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4264       }
4265       else
4266       {
4267         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4268         eRet = OMX_ErrorNoMore;
4269       }
4270     }
4271     else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4272     {
4273       if (profileLevelType->nProfileIndex == 0)
4274       {
4275         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4276         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4277       }
4278       else if(profileLevelType->nProfileIndex == 1)
4279       {
4280         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4281         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4282       }
4283       else
4284       {
4285         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4286         eRet = OMX_ErrorNoMore;
4287       }
4288     }
4289   }
4290   else
4291   {
4292     DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4293     eRet = OMX_ErrorBadPortIndex;
4294   }
4295   DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4296                     profileLevelType->eProfile,profileLevelType->eLevel);
4297   return eRet;
4298 }
4299 
4300 #ifdef USE_ION
alloc_map_ion_memory(int size,struct ion_allocation_data * alloc_data,struct ion_fd_data * fd_data,int flag)4301 int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
4302                                     struct ion_fd_data *fd_data,int flag)
4303 {
4304   struct venc_ion buf_ion_info;
4305   int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
4306   if (size <=0 || !alloc_data || !fd_data) {
4307     DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory");
4308     return -EINVAL;
4309 	}
4310     ion_dev_flags = O_RDONLY;
4311         ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
4312         if(ion_device_fd < 0)
4313         {
4314            DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
4315            return ion_device_fd;
4316         }
4317         alloc_data->len = size;
4318         alloc_data->align = 4096;
4319         alloc_data->flags = 0;
4320         if(!secure_session && (flag & ION_FLAG_CACHED))
4321         {
4322           alloc_data->flags = ION_FLAG_CACHED;
4323         }
4324 
4325         if (secure_session)
4326            alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
4327         else
4328            alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) |
4329                 ION_HEAP(ION_IOMMU_HEAP_ID));
4330 
4331         rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
4332         if(rc || !alloc_data->handle) {
4333            DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
4334            alloc_data->handle =NULL;
4335            close(ion_device_fd);
4336            ion_device_fd = -1;
4337            return ion_device_fd;
4338         }
4339         fd_data->handle = alloc_data->handle;
4340         rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
4341         if(rc) {
4342             DEBUG_PRINT_ERROR("\n ION MAP failed ");
4343             buf_ion_info.ion_alloc_data = *alloc_data;
4344             buf_ion_info.ion_device_fd = ion_device_fd;
4345             buf_ion_info.fd_ion_data = *fd_data;
4346             free_ion_memory(&buf_ion_info);
4347             fd_data->fd =-1;
4348             ion_device_fd =-1;
4349         }
4350         return ion_device_fd;
4351 }
4352 
free_ion_memory(struct venc_ion * buf_ion_info)4353 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
4354 {
4355      if (!buf_ion_info) {
4356         DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory");
4357         return;
4358      }
4359      if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
4360               &buf_ion_info->ion_alloc_data.handle)) {
4361          DEBUG_PRINT_ERROR("\n ION free failed ");
4362          return;
4363      }
4364      close(buf_ion_info->ion_device_fd);
4365      buf_ion_info->ion_alloc_data.handle = NULL;
4366      buf_ion_info->ion_device_fd = -1;
4367      buf_ion_info->fd_ion_data.fd = -1;
4368 }
4369 #endif
4370 #endif
4371 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)4372 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
4373 {
4374   if(buffer && meta_mode_enable)
4375   {
4376     encoder_media_buffer_type *media_ptr;
4377     struct pmem Input_pmem;
4378     unsigned int index_pmem = 0;
4379     bool meta_error = false;
4380 
4381     index_pmem = (buffer - m_inp_mem_ptr);
4382     if(mUseProxyColorFormat &&
4383        (index_pmem < m_sInPortDef.nBufferCountActual)) {
4384         if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){
4385           DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed");
4386         }
4387     } else {
4388       media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
4389       if(media_ptr && media_ptr->meta_handle)
4390       {
4391         if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
4392            media_ptr->meta_handle->numFds == 1 &&
4393            media_ptr->meta_handle->numInts == 2) {
4394           Input_pmem.fd = media_ptr->meta_handle->data[0];
4395           Input_pmem.buffer = media_ptr;
4396           Input_pmem.size = media_ptr->meta_handle->data[2];
4397           Input_pmem.offset = media_ptr->meta_handle->data[1];
4398           DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
4399                             Input_pmem.offset,
4400                             Input_pmem.size);
4401         } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
4402           private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
4403           Input_pmem.buffer = media_ptr;
4404           Input_pmem.fd = handle->fd;
4405           Input_pmem.offset = 0;
4406           Input_pmem.size = handle->size;
4407         } else {
4408           meta_error = true;
4409           DEBUG_PRINT_ERROR(" Meta Error set in EBD");
4410         }
4411         if(!meta_error)
4412            meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
4413           if(meta_error)
4414           {
4415            DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
4416                input_flush_progress);
4417           }
4418         }
4419      }
4420   }
4421 }
4422 #endif
omx_c2d_conv()4423 omx_video::omx_c2d_conv::omx_c2d_conv()
4424 {
4425   c2dcc = NULL;
4426   mLibHandle = NULL;
4427   mConvertOpen = NULL;
4428   mConvertClose = NULL;
4429   src_format = NV12_2K;
4430 }
4431 
init()4432 bool omx_video::omx_c2d_conv::init() {
4433   bool status = true;
4434   if(mLibHandle || mConvertOpen || mConvertClose) {
4435     DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice");
4436     status = false;
4437   }
4438   if(status) {
4439     mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
4440     if(mLibHandle){
4441        mConvertOpen = (createC2DColorConverter_t *)
4442        dlsym(mLibHandle,"createC2DColorConverter");
4443        mConvertClose = (destroyC2DColorConverter_t *)
4444        dlsym(mLibHandle,"destroyC2DColorConverter");
4445        if(!mConvertOpen || !mConvertClose)
4446          status = false;
4447     } else
4448       status = false;
4449   }
4450   if(!status && mLibHandle){
4451     dlclose(mLibHandle);
4452     mLibHandle = NULL;
4453     mConvertOpen = NULL;
4454     mConvertClose = NULL;
4455   }
4456   return status;
4457 }
4458 
convert(int src_fd,void * src_viraddr,int dest_fd,void * dest_viraddr)4459 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_viraddr,
4460      int dest_fd,void *dest_viraddr)
4461 {
4462   int result;
4463   if(!src_viraddr || !dest_viraddr || !c2dcc){
4464     DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert");
4465     return false;
4466   }
4467   result =  c2dcc->convertC2D(src_fd,src_viraddr,
4468                               dest_fd,dest_viraddr);
4469   DEBUG_PRINT_LOW("\n Color convert status %d",result);
4470   return ((result < 0)?false:true);
4471 }
4472 
open(unsigned int height,unsigned int width,ColorConvertFormat src,ColorConvertFormat dest)4473 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
4474      ColorConvertFormat src, ColorConvertFormat dest)
4475 {
4476   bool status = false;
4477   if(!c2dcc) {
4478      c2dcc = mConvertOpen(width, height, width, height,
4479              src,dest,0);
4480      if(c2dcc) {
4481        src_format = src;
4482        status = true;
4483      } else
4484        DEBUG_PRINT_ERROR("\n mConvertOpen failed");
4485   }
4486    return status;
4487 }
close()4488 void omx_video::omx_c2d_conv::close()
4489 {
4490   if(mLibHandle) {
4491     if(mConvertClose && c2dcc)
4492      mConvertClose(c2dcc);
4493     c2dcc = NULL;
4494   }
4495 }
~omx_c2d_conv()4496 omx_video::omx_c2d_conv::~omx_c2d_conv()
4497 {
4498   DEBUG_PRINT_ERROR("\n Destroy C2D instance");
4499   if(mLibHandle) {
4500     if(mConvertClose && c2dcc)
4501       mConvertClose(c2dcc);
4502     dlclose(mLibHandle);
4503   }
4504   c2dcc = NULL;
4505   mLibHandle = NULL;
4506   mConvertOpen = NULL;
4507   mConvertClose = NULL;
4508 }
get_src_format()4509 int omx_video::omx_c2d_conv::get_src_format()
4510 {
4511   int format = -1;
4512   if(src_format == NV12_2K) {
4513     format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
4514   } else if(src_format == RGBA8888) {
4515     format = HAL_PIXEL_FORMAT_RGBA_8888;
4516   }
4517   return format;
4518 }
get_buffer_size(int port,unsigned int & buf_size)4519 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
4520 {
4521   int cret = 0;
4522   bool ret = false;
4523   C2DBuffReq bufferreq;
4524   if(c2dcc){
4525     bufferreq.size = 0;
4526     cret = c2dcc->getBuffReq(port,&bufferreq);
4527     DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret);
4528     ret = (cret)?false:true;
4529     buf_size = bufferreq.size;
4530   }
4531   return ret;
4532 }
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4533 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
4534                                                   OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4535 {
4536   unsigned nBufIndex = 0;
4537   OMX_ERRORTYPE ret = OMX_ErrorNone;
4538   encoder_media_buffer_type *media_buffer;
4539   DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer);
4540 
4541   if(buffer == NULL) {
4542     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer);
4543     return OMX_ErrorBadParameter;
4544   }
4545   nBufIndex = buffer - meta_buffer_hdr;
4546   if(nBufIndex >= m_sInPortDef.nBufferCountActual) {
4547     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n",
4548                       nBufIndex);
4549     return OMX_ErrorBadParameter;
4550   }
4551   media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
4552   private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4553   /*Enable following code once private handle color format is
4554     updated correctly*/
4555 
4556   if(buffer->nFilledLen > 0) {
4557     if(c2d_opened && handle->format != c2d_conv.get_src_format()) {
4558       c2d_conv.close();
4559       c2d_opened = false;
4560     }
4561     if (!c2d_opened) {
4562         if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
4563           DEBUG_PRINT_ERROR("\n open Color conv for RGBA888");
4564           if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
4565                m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K)){
4566              m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4567              DEBUG_PRINT_ERROR("\n Color conv open failed");
4568              return OMX_ErrorBadParameter;
4569           }
4570           c2d_opened = true;
4571         } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
4572           DEBUG_PRINT_ERROR("\n Incorrect color format");
4573           m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4574           return OMX_ErrorBadParameter;
4575         }
4576     }
4577   }
4578 
4579   if(input_flush_progress == true)
4580   {
4581     m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4582     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress");
4583     return OMX_ErrorNone;
4584   }
4585 
4586   if(!psource_frame) {
4587     psource_frame = buffer;
4588     ret = push_input_buffer(hComp);
4589   } else {
4590     if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) {
4591       DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full");
4592       ret = OMX_ErrorBadParameter;
4593     }
4594   }
4595   if(ret != OMX_ErrorNone) {
4596     m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4597     DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:");
4598   }
4599   return ret;
4600 }
queue_meta_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info)4601 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
4602      struct pmem &Input_pmem_info) {
4603 
4604   OMX_ERRORTYPE ret = OMX_ErrorNone;
4605   unsigned address = 0,p2,id;
4606 
4607   DEBUG_PRINT_LOW("\n In queue Meta Buffer");
4608   if(!psource_frame || !pdest_frame) {
4609     DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4610     return OMX_ErrorBadParameter;
4611   }
4612 
4613   if(psource_frame->nFilledLen > 0) {
4614    if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
4615      DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4616      post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
4617      ret = OMX_ErrorBadParameter;
4618    }
4619   }
4620 
4621   if(ret == OMX_ErrorNone)
4622     ret = empty_this_buffer_proxy(hComp,psource_frame);
4623 
4624   if(ret == OMX_ErrorNone) {
4625     psource_frame = NULL;
4626     if(!psource_frame && m_opq_meta_q.m_size) {
4627       m_opq_meta_q.pop_entry(&address,&p2,&id);
4628       psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4629     }
4630   }
4631   return ret;
4632 }
4633 
convert_queue_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info,unsigned & index)4634 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
4635      struct pmem &Input_pmem_info,unsigned &index){
4636 
4637   unsigned char *uva;
4638   OMX_ERRORTYPE ret = OMX_ErrorNone;
4639   unsigned address = 0,p2,id;
4640 
4641   DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer");
4642   if(!psource_frame || !pdest_frame) {
4643     DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4644     return OMX_ErrorBadParameter;
4645   }
4646 
4647   if(!psource_frame->nFilledLen){
4648     if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){
4649         pdest_frame->nFilledLen = psource_frame->nFilledLen;
4650         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4651         pdest_frame->nFlags = psource_frame->nFlags;
4652         DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \
4653           Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen);
4654     } else {
4655         pdest_frame->nOffset = 0;
4656         pdest_frame->nFilledLen = 0;
4657         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4658         pdest_frame->nFlags = psource_frame->nFlags;
4659         DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4660            pdest_frame,pdest_frame->nFilledLen);
4661     }
4662   } else {
4663      uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
4664                            PROT_READ|PROT_WRITE,
4665                            MAP_SHARED,Input_pmem_info.fd,0);
4666      if(uva == MAP_FAILED) {
4667        ret = OMX_ErrorBadParameter;
4668      } else {
4669        if(!c2d_conv.convert(Input_pmem_info.fd,uva,
4670           m_pInput_pmem[index].fd,pdest_frame->pBuffer)) {
4671           DEBUG_PRINT_ERROR("\n Color Conversion failed");
4672           ret = OMX_ErrorBadParameter;
4673        } else {
4674           unsigned int buf_size = 0;
4675           if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
4676             ret = OMX_ErrorBadParameter;
4677           else {
4678             pdest_frame->nOffset = 0;
4679             if(!buf_size || buf_size > pdest_frame->nAllocLen) {
4680               DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer"
4681                "size mismatch buf size %d alloc size %d",
4682                       buf_size, pdest_frame->nAllocLen);
4683               ret = OMX_ErrorBadParameter;
4684               buf_size = 0;
4685             }
4686             pdest_frame->nFilledLen = buf_size;
4687             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4688             pdest_frame->nFlags = psource_frame->nFlags;
4689             DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4690                pdest_frame,pdest_frame->nFilledLen);
4691            }
4692          }
4693          munmap(uva,Input_pmem_info.size);
4694       }
4695     }
4696     if((ret == OMX_ErrorNone) &&
4697        dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
4698       DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4699       post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
4700       ret = OMX_ErrorBadParameter;
4701     }
4702     if(ret == OMX_ErrorNone)
4703       ret = empty_this_buffer_proxy(hComp,pdest_frame);
4704     if(ret == OMX_ErrorNone) {
4705       m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
4706       psource_frame = NULL;
4707       pdest_frame = NULL;
4708       if(!psource_frame && m_opq_meta_q.m_size) {
4709         m_opq_meta_q.pop_entry(&address,&p2,&id);
4710         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4711       }
4712       if(!pdest_frame && m_opq_pmem_q.m_size) {
4713         m_opq_pmem_q.pop_entry(&address,&p2,&id);
4714         pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4715         DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame);
4716       }
4717     }
4718     return ret;
4719 }
4720 
push_input_buffer(OMX_HANDLETYPE hComp)4721 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
4722 {
4723   unsigned address = 0,p2,id, index = 0;
4724   OMX_ERRORTYPE ret = OMX_ErrorNone;
4725 
4726   if(!psource_frame && m_opq_meta_q.m_size) {
4727     m_opq_meta_q.pop_entry(&address,&p2,&id);
4728     psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4729   }
4730   if(!pdest_frame && m_opq_pmem_q.m_size) {
4731     m_opq_pmem_q.pop_entry(&address,&p2,&id);
4732     pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4733   }
4734   while(psource_frame != NULL && pdest_frame != NULL &&
4735         ret == OMX_ErrorNone) {
4736     struct pmem Input_pmem_info;
4737     encoder_media_buffer_type *media_buffer;
4738     index = pdest_frame - m_inp_mem_ptr;
4739     if(index >= m_sInPortDef.nBufferCountActual){
4740        DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d",
4741                          index,m_sInPortDef.nBufferCountActual);
4742        return OMX_ErrorBadParameter;
4743     }
4744     media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
4745     /*Will enable to verify camcorder in current TIPS can be removed*/
4746     if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
4747       Input_pmem_info.buffer = media_buffer;
4748       Input_pmem_info.fd = media_buffer->meta_handle->data[0];
4749       Input_pmem_info.offset = media_buffer->meta_handle->data[1];
4750       Input_pmem_info.size = media_buffer->meta_handle->data[2];
4751       DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
4752                         Input_pmem_info.offset,
4753                         Input_pmem_info.size);
4754       ret = queue_meta_buffer(hComp,Input_pmem_info);
4755     } else if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) {
4756        ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4757     } else {
4758       private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4759       Input_pmem_info.buffer = media_buffer;
4760       Input_pmem_info.fd = handle->fd;
4761       Input_pmem_info.offset = 0;
4762       Input_pmem_info.size = handle->size;
4763       if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
4764         ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4765       else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
4766         ret = queue_meta_buffer(hComp,Input_pmem_info);
4767       else
4768         ret = OMX_ErrorBadParameter;
4769     }
4770    }
4771   return ret;
4772 }
4773