1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2012, 2015 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(): msg_thread_id(0),
227                         async_thread_id(0),
228                         m_state(OMX_StateInvalid),
229                         m_app_data(NULL),
230                         m_inp_mem_ptr(NULL),
231                         m_out_mem_ptr(NULL),
232                         m_pInput_pmem(NULL),
233                         m_pOutput_pmem(NULL),
234 #ifdef USE_ION
235                         m_pInput_ion(NULL),
236                         m_pOutput_ion(NULL),
237 #endif
238                         pending_input_buffers(0),
239                         pending_output_buffers(0),
240                         m_out_bm_count(0),
241                         m_inp_bm_count(0),
242                         m_flags(0),
243                         m_event_port_settings_sent(false),
244                         output_flush_progress (false),
245                         input_flush_progress (false),
246                         input_use_buffer (false),
247                         output_use_buffer (false),
248                         m_use_input_pmem(OMX_FALSE),
249                         m_use_output_pmem(OMX_FALSE),
250                         m_etb_count(0),
251                         m_fbd_count(0),
252                         m_pipe_in(-1),
253                         m_pipe_out(-1),
254                         m_error_propogated(false),
255                         m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
256                         psource_frame(NULL),
257                         pdest_frame(NULL),
258                         c2d_opened(false),
259                         secure_session(false)
260 {
261   DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
262   memset(&m_cmp,0,sizeof(m_cmp));
263   memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
264   secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar;
265   pthread_mutex_init(&m_lock, NULL);
266   sem_init(&m_cmd_lock,0,0);
267 }
268 
269 
270 /* ======================================================================
271 FUNCTION
272   omx_venc::~omx_venc
273 
274 DESCRIPTION
275   Destructor
276 
277 PARAMETERS
278   None
279 
280 RETURN VALUE
281   None.
282 ========================================================================== */
~omx_video()283 omx_video::~omx_video()
284 {
285   DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
286   if(m_pipe_in >= 0) close(m_pipe_in);
287   if(m_pipe_out >= 0) close(m_pipe_out);
288   DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
289   if (msg_thread_id != 0) {
290     pthread_join(msg_thread_id,NULL);
291   }
292   DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
293   if (async_thread_id != 0) {
294     pthread_join(async_thread_id,NULL);
295   }
296   pthread_mutex_destroy(&m_lock);
297   sem_destroy(&m_cmd_lock);
298   DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
299       m_fbd_count);
300   DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
301   DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
302 }
303 
304 /* ======================================================================
305 FUNCTION
306   omx_venc::OMXCntrlProcessMsgCb
307 
308 DESCRIPTION
309   IL Client callbacks are generated through this routine. The decoder
310   provides the thread context for this routine.
311 
312 PARAMETERS
313   ctxt -- Context information related to the self.
314   id   -- Event identifier. This could be any of the following:
315           1. Command completion event
316           2. Buffer done callback event
317           3. Frame done callback event
318 
319 RETURN VALUE
320   None.
321 
322 ========================================================================== */
process_event_cb(void * ctxt,unsigned char id)323 void omx_video::process_event_cb(void *ctxt, unsigned char id)
324 {
325   unsigned p1; // Parameter - 1
326   unsigned p2; // Parameter - 2
327   unsigned ident;
328   unsigned qsize=0; // qsize
329   omx_video *pThis = (omx_video *) ctxt;
330 
331   if(!pThis)
332   {
333     DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
334     return;
335   }
336 
337   // Protect the shared queue data structure
338   do
339   {
340     /*Read the message id's from the queue*/
341 
342     pthread_mutex_lock(&pThis->m_lock);
343     qsize = pThis->m_cmd_q.m_size;
344     if(qsize)
345     {
346       pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
347     }
348 
349     if(qsize == 0)
350     {
351       qsize = pThis->m_ftb_q.m_size;
352       if(qsize)
353       {
354         pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
355       }
356     }
357 
358     if(qsize == 0)
359     {
360       qsize = pThis->m_etb_q.m_size;
361       if(qsize)
362       {
363         pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
364       }
365     }
366 
367     pthread_mutex_unlock(&pThis->m_lock);
368 
369     /*process message if we have one*/
370     if(qsize > 0)
371     {
372       id = ident;
373       switch(id)
374       {
375       case OMX_COMPONENT_GENERATE_EVENT:
376         if(pThis->m_pCallbacks.EventHandler)
377         {
378           switch(p1)
379           {
380           case OMX_CommandStateSet:
381             pThis->m_state = (OMX_STATETYPE) p2;
382             DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
383             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
384                                              OMX_EventCmdComplete, p1, p2, NULL);
385             break;
386 
387           case OMX_EventError:
388             DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
389             if(p2 == OMX_ErrorHardware)
390             {
391               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
392                                                OMX_EventError,OMX_ErrorHardware,0,NULL);
393             }
394             else
395             {
396               pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
397                                                OMX_EventError, p2, NULL, NULL );
398 
399             }
400             break;
401 
402           case OMX_CommandPortDisable:
403             DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
404                         "state \n", p2);
405             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
406                                              OMX_EventCmdComplete, p1, p2, NULL );
407             break;
408           case OMX_CommandPortEnable:
409             DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
410                         , p2);
411             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
412                                              OMX_EventCmdComplete, p1, p2, NULL );
413             break;
414 
415           default:
416             DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1);
417             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
418                                              OMX_EventCmdComplete, p1, p2, NULL );
419             break;
420 
421           }
422         }
423         else
424         {
425           DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
426         }
427         break;
428       case OMX_COMPONENT_GENERATE_ETB_OPQ:
429         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n");
430         if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
431                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
432         {
433           DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
434           pThis->omx_report_error ();
435         }
436         break;
437       case OMX_COMPONENT_GENERATE_ETB:
438         DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n");
439         if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
440                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
441         {
442           DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
443           pThis->omx_report_error ();
444         }
445         break;
446 
447       case OMX_COMPONENT_GENERATE_FTB:
448         if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
449                                           (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
450         {
451           DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
452           pThis->omx_report_error ();
453         }
454         break;
455 
456       case OMX_COMPONENT_GENERATE_COMMAND:
457         pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
458                                   (OMX_U32)p2,(OMX_PTR)NULL);
459         break;
460 
461       case OMX_COMPONENT_GENERATE_EBD:
462         if( pThis->empty_buffer_done(&pThis->m_cmp,
463                                      (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
464         {
465           DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
466           pThis->omx_report_error ();
467         }
468         break;
469 
470       case OMX_COMPONENT_GENERATE_FBD:
471         if( pThis->fill_buffer_done(&pThis->m_cmp,
472                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
473         {
474           DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
475           pThis->omx_report_error ();
476         }
477         break;
478 
479       case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
480 
481         pThis->input_flush_progress = false;
482         DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
483         m_etb_count = 0;
484         if(pThis->m_pCallbacks.EventHandler)
485         {
486           /*Check if we need generate event for Flush done*/
487           if(BITMASK_PRESENT(&pThis->m_flags,
488                              OMX_COMPONENT_INPUT_FLUSH_PENDING))
489           {
490             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
491             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
492                                              OMX_EventCmdComplete,OMX_CommandFlush,
493                                              PORT_INDEX_IN,NULL );
494           }
495           else if(BITMASK_PRESENT(&pThis->m_flags,
496                                   OMX_COMPONENT_IDLE_PENDING))
497           {
498             if(!pThis->output_flush_progress)
499             {
500               DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n");
501               if(dev_stop() != 0)
502               {
503                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
504                 pThis->omx_report_error ();
505               }
506             }
507           }
508         }
509 
510         break;
511 
512       case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
513 
514         pThis->output_flush_progress = false;
515         DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
516         m_fbd_count = 0;
517         if(pThis->m_pCallbacks.EventHandler)
518         {
519           /*Check if we need generate event for Flush done*/
520           if(BITMASK_PRESENT(&pThis->m_flags,
521                              OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
522           {
523             BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
524 
525             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
526                                              OMX_EventCmdComplete,OMX_CommandFlush,
527                                              PORT_INDEX_OUT,NULL );
528           }
529           else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
530           {
531             DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n");
532             if(!pThis->input_flush_progress)
533             {
534               if(dev_stop() != 0)
535               {
536                 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
537                 pThis->omx_report_error ();
538               }
539             }
540           }
541         }
542         break;
543 
544       case OMX_COMPONENT_GENERATE_START_DONE:
545         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
546 
547         if(pThis->m_pCallbacks.EventHandler)
548         {
549           DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
550           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
551           {
552             DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
553                              executing");
554             // Send the callback now
555             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
556             pThis->m_state = OMX_StateExecuting;
557             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
558                                              OMX_EventCmdComplete,OMX_CommandStateSet,
559                                              OMX_StateExecuting, NULL);
560           }
561           else if(BITMASK_PRESENT(&pThis->m_flags,
562                                   OMX_COMPONENT_PAUSE_PENDING))
563           {
564             if(dev_pause())
565             {
566               DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
567               pThis->omx_report_error ();
568             }
569           }
570           else if (BITMASK_PRESENT(&pThis->m_flags,
571                                    OMX_COMPONENT_LOADED_START_PENDING))
572           {
573             if(dev_loaded_start_done())
574             {
575               DEBUG_PRINT_LOW("successful loaded Start Done!");
576             }
577             else
578             {
579               DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
580               pThis->omx_report_error ();
581             }
582             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
583           }
584           else
585           {
586             DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
587           }
588         }
589         else
590         {
591           DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
592         }
593         break;
594 
595       case OMX_COMPONENT_GENERATE_PAUSE_DONE:
596         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
597         if(pThis->m_pCallbacks.EventHandler)
598         {
599           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
600           {
601             //Send the callback now
602             pThis->complete_pending_buffer_done_cbs();
603             DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n");
604             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
605             pThis->m_state = OMX_StatePause;
606             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
607                                              OMX_EventCmdComplete,OMX_CommandStateSet,
608                                              OMX_StatePause, NULL);
609           }
610         }
611 
612         break;
613 
614       case OMX_COMPONENT_GENERATE_RESUME_DONE:
615         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
616         if(pThis->m_pCallbacks.EventHandler)
617         {
618           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
619           {
620             // Send the callback now
621             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
622             pThis->m_state = OMX_StateExecuting;
623             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
624                                              OMX_EventCmdComplete,OMX_CommandStateSet,
625                                              OMX_StateExecuting,NULL);
626           }
627         }
628 
629         break;
630 
631       case OMX_COMPONENT_GENERATE_STOP_DONE:
632         DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
633         if(pThis->m_pCallbacks.EventHandler)
634         {
635           pThis->complete_pending_buffer_done_cbs();
636           if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
637           {
638             // Send the callback now
639             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
640             pThis->m_state = OMX_StateIdle;
641             pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
642                                              OMX_EventCmdComplete,OMX_CommandStateSet,
643                                              OMX_StateIdle,NULL);
644           }
645           else if (BITMASK_PRESENT(&pThis->m_flags,
646                                    OMX_COMPONENT_LOADED_STOP_PENDING))
647           {
648             if(dev_loaded_stop_done())
649             {
650               DEBUG_PRINT_LOW("successful loaded Stop Done!");
651             }
652             else
653             {
654               DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
655               pThis->omx_report_error ();
656             }
657             BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
658           }
659           else
660           {
661             DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
662           }
663         }
664 
665         break;
666 
667       case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
668         DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
669         pThis->omx_report_error ();
670         break;
671 
672       default:
673         DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id);
674         break;
675       }
676     }
677 
678     pthread_mutex_lock(&pThis->m_lock);
679     qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
680             pThis->m_etb_q.m_size;
681 
682     pthread_mutex_unlock(&pThis->m_lock);
683 
684   }
685   while(qsize>0);
686   DEBUG_PRINT_LOW("\n exited the while loop\n");
687 
688 }
689 
690 
691 
692 
693 /* ======================================================================
694 FUNCTION
695   omx_venc::GetComponentVersion
696 
697 DESCRIPTION
698   Returns the component version.
699 
700 PARAMETERS
701   TBD.
702 
703 RETURN VALUE
704   OMX_ErrorNone.
705 
706 ========================================================================== */
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)707 OMX_ERRORTYPE  omx_video::get_component_version
708 (
709 OMX_IN OMX_HANDLETYPE hComp,
710 OMX_OUT OMX_STRING componentName,
711 OMX_OUT OMX_VERSIONTYPE* componentVersion,
712 OMX_OUT OMX_VERSIONTYPE* specVersion,
713 OMX_OUT OMX_UUIDTYPE* componentUUID
714 )
715 {
716   if(m_state == OMX_StateInvalid)
717   {
718     DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
719     return OMX_ErrorInvalidState;
720   }
721   /* TBD -- Return the proper version */
722   if (specVersion)
723   {
724     specVersion->nVersion = OMX_SPEC_VERSION;
725   }
726   return OMX_ErrorNone;
727 }
728 /* ======================================================================
729 FUNCTION
730   omx_venc::SendCommand
731 
732 DESCRIPTION
733   Returns zero if all the buffers released..
734 
735 PARAMETERS
736   None.
737 
738 RETURN VALUE
739   true/false
740 
741 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)742 OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
743                                        OMX_IN OMX_COMMANDTYPE cmd,
744                                        OMX_IN OMX_U32 param1,
745                                        OMX_IN OMX_PTR cmdData
746                                       )
747 {
748   if(m_state == OMX_StateInvalid)
749   {
750     DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
751     return OMX_ErrorInvalidState;
752   }
753 
754   if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
755   {
756     if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
757     {
758       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
759       return OMX_ErrorBadPortIndex;
760     }
761   }
762   if(cmd == OMX_CommandMarkBuffer)
763   {
764     if(param1 != PORT_INDEX_IN)
765     {
766       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
767       return OMX_ErrorBadPortIndex;
768     }
769     if(!cmdData)
770     {
771       DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
772       return OMX_ErrorBadParameter;
773     }
774   }
775 
776   post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
777   sem_wait(&m_cmd_lock);
778   return OMX_ErrorNone;
779 }
780 
781 /* ======================================================================
782 FUNCTION
783   omx_venc::SendCommand
784 
785 DESCRIPTION
786   Returns zero if all the buffers released..
787 
788 PARAMETERS
789   None.
790 
791 RETURN VALUE
792   true/false
793 
794 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)795 OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
796                                              OMX_IN OMX_COMMANDTYPE cmd,
797                                              OMX_IN OMX_U32 param1,
798                                              OMX_IN OMX_PTR cmdData
799                                             )
800 {
801   OMX_ERRORTYPE eRet = OMX_ErrorNone;
802   OMX_STATETYPE eState = (OMX_STATETYPE) param1;
803   int bFlag = 1;
804 
805   if(cmd == OMX_CommandStateSet)
806   {
807     /***************************/
808     /* Current State is Loaded */
809     /***************************/
810     if(m_state == OMX_StateLoaded)
811     {
812       if(eState == OMX_StateIdle)
813       {
814         //if all buffers are allocated or all ports disabled
815         if(allocate_done() ||
816            ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
817         {
818           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
819         }
820         else
821         {
822           DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
823           BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
824           // Skip the event notification
825           bFlag = 0;
826         }
827       }
828       /* Requesting transition from Loaded to Loaded */
829       else if(eState == OMX_StateLoaded)
830       {
831         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n");
832         post_event(OMX_EventError,OMX_ErrorSameState,\
833                    OMX_COMPONENT_GENERATE_EVENT);
834         eRet = OMX_ErrorSameState;
835       }
836       /* Requesting transition from Loaded to WaitForResources */
837       else if(eState == OMX_StateWaitForResources)
838       {
839         /* Since error is None , we will post an event
840            at the end of this function definition */
841         DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
842       }
843       /* Requesting transition from Loaded to Executing */
844       else if(eState == OMX_StateExecuting)
845       {
846         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
847         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
848                    OMX_COMPONENT_GENERATE_EVENT);
849         eRet = OMX_ErrorIncorrectStateTransition;
850       }
851       /* Requesting transition from Loaded to Pause */
852       else if(eState == OMX_StatePause)
853       {
854         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
855         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
856                    OMX_COMPONENT_GENERATE_EVENT);
857         eRet = OMX_ErrorIncorrectStateTransition;
858       }
859       /* Requesting transition from Loaded to Invalid */
860       else if(eState == OMX_StateInvalid)
861       {
862         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
863         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
864         eRet = OMX_ErrorInvalidState;
865       }
866       else
867       {
868         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
869                           eState);
870         eRet = OMX_ErrorBadParameter;
871       }
872     }
873 
874     /***************************/
875     /* Current State is IDLE */
876     /***************************/
877     else if(m_state == OMX_StateIdle)
878     {
879       if(eState == OMX_StateLoaded)
880       {
881         if(release_done())
882         {
883           /*
884              Since error is None , we will post an event at the end
885              of this function definition
886           */
887           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
888           if(dev_stop() != 0)
889           {
890             DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
891             eRet = OMX_ErrorHardware;
892           }
893         }
894         else
895         {
896           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
897           BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
898           // Skip the event notification
899           bFlag = 0;
900         }
901       }
902       /* Requesting transition from Idle to Executing */
903       else if(eState == OMX_StateExecuting)
904       {
905         if( dev_start() )
906         {
907           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
908           omx_report_error ();
909           eRet = OMX_ErrorHardware;
910         }
911         else
912         {
913           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
914           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
915           bFlag = 0;
916         }
917 
918 	dev_start_done();
919       }
920       /* Requesting transition from Idle to Idle */
921       else if(eState == OMX_StateIdle)
922       {
923         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
924         post_event(OMX_EventError,OMX_ErrorSameState,\
925                    OMX_COMPONENT_GENERATE_EVENT);
926         eRet = OMX_ErrorSameState;
927       }
928       /* Requesting transition from Idle to WaitForResources */
929       else if(eState == OMX_StateWaitForResources)
930       {
931         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
932         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
933                    OMX_COMPONENT_GENERATE_EVENT);
934         eRet = OMX_ErrorIncorrectStateTransition;
935       }
936       /* Requesting transition from Idle to Pause */
937       else if(eState == OMX_StatePause)
938       {
939         /*To pause the Video core we need to start the driver*/
940         if( dev_start() )
941         {
942           DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
943           omx_report_error ();
944           eRet = OMX_ErrorHardware;
945         }
946         else
947         {
948           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
949           DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
950           bFlag = 0;
951         }
952       }
953       /* Requesting transition from Idle to Invalid */
954       else if(eState == OMX_StateInvalid)
955       {
956         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
957         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
958         eRet = OMX_ErrorInvalidState;
959       }
960       else
961       {
962         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
963         eRet = OMX_ErrorBadParameter;
964       }
965     }
966 
967     /******************************/
968     /* Current State is Executing */
969     /******************************/
970     else if(m_state == OMX_StateExecuting)
971     {
972       /* Requesting transition from Executing to Idle */
973       if(eState == OMX_StateIdle)
974       {
975         /* Since error is None , we will post an event
976         at the end of this function definition
977         */
978         DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
979         //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
980         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
981         execute_omx_flush(OMX_ALL);
982         bFlag = 0;
983 	dev_stop_done();
984       }
985       /* Requesting transition from Executing to Paused */
986       else if(eState == OMX_StatePause)
987       {
988 
989         if(dev_pause())
990         {
991           DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
992           post_event(OMX_EventError,OMX_ErrorHardware,\
993                      OMX_COMPONENT_GENERATE_EVENT);
994           eRet = OMX_ErrorHardware;
995         }
996         else
997         {
998           BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
999           DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n");
1000           bFlag = 0;
1001         }
1002       }
1003       /* Requesting transition from Executing to Loaded */
1004       else if(eState == OMX_StateLoaded)
1005       {
1006         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
1007         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1008                    OMX_COMPONENT_GENERATE_EVENT);
1009         eRet = OMX_ErrorIncorrectStateTransition;
1010       }
1011       /* Requesting transition from Executing to WaitForResources */
1012       else if(eState == OMX_StateWaitForResources)
1013       {
1014         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
1015         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1016                    OMX_COMPONENT_GENERATE_EVENT);
1017         eRet = OMX_ErrorIncorrectStateTransition;
1018       }
1019       /* Requesting transition from Executing to Executing */
1020       else if(eState == OMX_StateExecuting)
1021       {
1022         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
1023         post_event(OMX_EventError,OMX_ErrorSameState,\
1024                    OMX_COMPONENT_GENERATE_EVENT);
1025         eRet = OMX_ErrorSameState;
1026       }
1027       /* Requesting transition from Executing to Invalid */
1028       else if(eState == OMX_StateInvalid)
1029       {
1030         DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
1031         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1032         eRet = OMX_ErrorInvalidState;
1033       }
1034       else
1035       {
1036         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
1037         eRet = OMX_ErrorBadParameter;
1038       }
1039     }
1040     /***************************/
1041     /* Current State is Pause  */
1042     /***************************/
1043     else if(m_state == OMX_StatePause)
1044     {
1045       /* Requesting transition from Pause to Executing */
1046       if(eState == OMX_StateExecuting)
1047       {
1048         DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1049         if( dev_resume() )
1050         {
1051           post_event(OMX_EventError,OMX_ErrorHardware,\
1052                      OMX_COMPONENT_GENERATE_EVENT);
1053           eRet = OMX_ErrorHardware;
1054         }
1055         else
1056         {
1057           BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1058           DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n");
1059           post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE);
1060           bFlag = 0;
1061         }
1062       }
1063       /* Requesting transition from Pause to Idle */
1064       else if(eState == OMX_StateIdle)
1065       {
1066         /* Since error is None , we will post an event
1067         at the end of this function definition */
1068         DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1069         BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1070         execute_omx_flush(OMX_ALL);
1071         bFlag = 0;
1072       }
1073       /* Requesting transition from Pause to loaded */
1074       else if(eState == OMX_StateLoaded)
1075       {
1076         DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
1077         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1078                    OMX_COMPONENT_GENERATE_EVENT);
1079         eRet = OMX_ErrorIncorrectStateTransition;
1080       }
1081       /* Requesting transition from Pause to WaitForResources */
1082       else if(eState == OMX_StateWaitForResources)
1083       {
1084         DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
1085         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1086                    OMX_COMPONENT_GENERATE_EVENT);
1087         eRet = OMX_ErrorIncorrectStateTransition;
1088       }
1089       /* Requesting transition from Pause to Pause */
1090       else if(eState == OMX_StatePause)
1091       {
1092         DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
1093         post_event(OMX_EventError,OMX_ErrorSameState,\
1094                    OMX_COMPONENT_GENERATE_EVENT);
1095         eRet = OMX_ErrorSameState;
1096       }
1097       /* Requesting transition from Pause to Invalid */
1098       else if(eState == OMX_StateInvalid)
1099       {
1100         DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
1101         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1102         eRet = OMX_ErrorInvalidState;
1103       }
1104       else
1105       {
1106         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
1107         eRet = OMX_ErrorBadParameter;
1108       }
1109     }
1110     /***************************/
1111     /* Current State is WaitForResources  */
1112     /***************************/
1113     else if(m_state == OMX_StateWaitForResources)
1114     {
1115       /* Requesting transition from WaitForResources to Loaded */
1116       if(eState == OMX_StateLoaded)
1117       {
1118         /* Since error is None , we will post an event
1119         at the end of this function definition */
1120         DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
1121       }
1122       /* Requesting transition from WaitForResources to WaitForResources */
1123       else if(eState == OMX_StateWaitForResources)
1124       {
1125         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
1126         post_event(OMX_EventError,OMX_ErrorSameState,
1127                    OMX_COMPONENT_GENERATE_EVENT);
1128         eRet = OMX_ErrorSameState;
1129       }
1130       /* Requesting transition from WaitForResources to Executing */
1131       else if(eState == OMX_StateExecuting)
1132       {
1133         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
1134         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1135                    OMX_COMPONENT_GENERATE_EVENT);
1136         eRet = OMX_ErrorIncorrectStateTransition;
1137       }
1138       /* Requesting transition from WaitForResources to Pause */
1139       else if(eState == OMX_StatePause)
1140       {
1141         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
1142         post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1143                    OMX_COMPONENT_GENERATE_EVENT);
1144         eRet = OMX_ErrorIncorrectStateTransition;
1145       }
1146       /* Requesting transition from WaitForResources to Invalid */
1147       else if(eState == OMX_StateInvalid)
1148       {
1149         DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
1150         post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1151         eRet = OMX_ErrorInvalidState;
1152       }
1153       /* Requesting transition from WaitForResources to Loaded -
1154       is NOT tested by Khronos TS */
1155 
1156     }
1157     else
1158     {
1159       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
1160       eRet = OMX_ErrorBadParameter;
1161     }
1162   }
1163   /********************************/
1164   /* Current State is Invalid */
1165   /*******************************/
1166   else if(m_state == OMX_StateInvalid)
1167   {
1168     /* State Transition from Inavlid to any state */
1169     if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
1170                   || OMX_StateIdle || OMX_StateExecuting
1171                   || OMX_StatePause || OMX_StateInvalid))
1172     {
1173       DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
1174       post_event(OMX_EventError,OMX_ErrorInvalidState,\
1175                  OMX_COMPONENT_GENERATE_EVENT);
1176       eRet = OMX_ErrorInvalidState;
1177     }
1178   }
1179   else if(cmd == OMX_CommandFlush)
1180   {
1181     if(0 == param1 || OMX_ALL == param1)
1182     {
1183       BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1184     }
1185     if(1 == param1 || OMX_ALL == param1)
1186     {
1187       //generate output flush event only.
1188       BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1189     }
1190 
1191     execute_omx_flush(param1);
1192     bFlag = 0;
1193   }
1194   else if( cmd == OMX_CommandPortEnable)
1195   {
1196     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1197     {
1198       m_sInPortDef.bEnabled = OMX_TRUE;
1199 
1200       if( (m_state == OMX_StateLoaded &&
1201            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1202           || allocate_input_done())
1203       {
1204         post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
1205                    OMX_COMPONENT_GENERATE_EVENT);
1206       }
1207       else
1208       {
1209         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1210         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1211         // Skip the event notification
1212         bFlag = 0;
1213       }
1214     }
1215     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1216     {
1217       m_sOutPortDef.bEnabled = OMX_TRUE;
1218 
1219       if( (m_state == OMX_StateLoaded &&
1220            !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1221           || (allocate_output_done()))
1222       {
1223         post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
1224                    OMX_COMPONENT_GENERATE_EVENT);
1225 
1226       }
1227       else
1228       {
1229         DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1230         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1231         // Skip the event notification
1232         bFlag = 0;
1233       }
1234     }
1235   }
1236   else if(cmd == OMX_CommandPortDisable)
1237   {
1238     if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1239     {
1240       m_sInPortDef.bEnabled = OMX_FALSE;
1241       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1242          && release_input_done())
1243       {
1244         post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
1245                    OMX_COMPONENT_GENERATE_EVENT);
1246       }
1247       else
1248       {
1249         BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1250         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1251         {
1252           execute_omx_flush(PORT_INDEX_IN);
1253         }
1254 
1255         // Skip the event notification
1256         bFlag = 0;
1257       }
1258     }
1259     if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1260     {
1261       m_sOutPortDef.bEnabled = OMX_FALSE;
1262 
1263       if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1264          && release_output_done())
1265       {
1266         post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
1267                    OMX_COMPONENT_GENERATE_EVENT);
1268       }
1269       else
1270       {
1271         BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1272         if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1273         {
1274           execute_omx_flush(PORT_INDEX_OUT);
1275         }
1276         // Skip the event notification
1277         bFlag = 0;
1278 
1279       }
1280     }
1281   }
1282   else
1283   {
1284     DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
1285     eRet = OMX_ErrorNotImplemented;
1286   }
1287   if(eRet == OMX_ErrorNone && bFlag)
1288   {
1289     post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1290   }
1291   sem_post(&m_cmd_lock);
1292   return eRet;
1293 }
1294 
1295 /* ======================================================================
1296 FUNCTION
1297   omx_venc::ExecuteOmxFlush
1298 
1299 DESCRIPTION
1300   Executes the OMX flush.
1301 
1302 PARAMETERS
1303   flushtype - input flush(1)/output flush(0)/ both.
1304 
1305 RETURN VALUE
1306   true/false
1307 
1308 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)1309 bool omx_video::execute_omx_flush(OMX_U32 flushType)
1310 {
1311   bool bRet = false;
1312   DEBUG_PRINT_LOW("\n execute_omx_flush -  %d\n", flushType);
1313   if(flushType == 0 || flushType == OMX_ALL)
1314   {
1315     input_flush_progress = true;
1316     //flush input only
1317     bRet = execute_input_flush();
1318   }
1319   if(flushType == 1 || flushType == OMX_ALL)
1320   {
1321     //flush output only
1322     output_flush_progress = true;
1323     bRet = execute_output_flush();
1324   }
1325   return bRet;
1326 }
1327 /*=========================================================================
1328 FUNCTION : execute_output_flush
1329 
1330 DESCRIPTION
1331   Executes the OMX flush at OUTPUT PORT.
1332 
1333 PARAMETERS
1334   None.
1335 
1336 RETURN VALUE
1337   true/false
1338 ==========================================================================*/
execute_output_flush(void)1339 bool omx_video::execute_output_flush(void)
1340 {
1341   unsigned      p1 = 0; // Parameter - 1
1342   unsigned      p2 = 0; // Parameter - 2
1343   unsigned      ident = 0;
1344   bool bRet = true;
1345 
1346   /*Generate FBD for all Buffers in the FTBq*/
1347   DEBUG_PRINT_LOW("\n execute_output_flush\n");
1348   pthread_mutex_lock(&m_lock);
1349   while(m_ftb_q.m_size)
1350   {
1351     m_ftb_q.pop_entry(&p1,&p2,&ident);
1352 
1353     if(ident == OMX_COMPONENT_GENERATE_FTB )
1354     {
1355       pending_output_buffers++;
1356       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1357     }
1358     else if(ident == OMX_COMPONENT_GENERATE_FBD)
1359     {
1360       fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1361     }
1362   }
1363 
1364   pthread_mutex_unlock(&m_lock);
1365   /*Check if there are buffers with the Driver*/
1366   if(dev_flush(PORT_INDEX_OUT))
1367   {
1368     DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
1369     return false;
1370   }
1371 
1372   return bRet;
1373 }
1374 /*=========================================================================
1375 FUNCTION : execute_input_flush
1376 
1377 DESCRIPTION
1378   Executes the OMX flush at INPUT PORT.
1379 
1380 PARAMETERS
1381   None.
1382 
1383 RETURN VALUE
1384   true/false
1385 ==========================================================================*/
execute_input_flush(void)1386 bool omx_video::execute_input_flush(void)
1387 {
1388   unsigned      p1 = 0; // Parameter - 1
1389   unsigned      p2 = 0; // Parameter - 2
1390   unsigned      ident = 0;
1391   bool bRet = true;
1392 
1393   /*Generate EBD for all Buffers in the ETBq*/
1394   DEBUG_PRINT_LOW("\n execute_input_flush\n");
1395 
1396   pthread_mutex_lock(&m_lock);
1397   while(m_etb_q.m_size)
1398   {
1399     m_etb_q.pop_entry(&p1,&p2,&ident);
1400     if(ident == OMX_COMPONENT_GENERATE_ETB)
1401     {
1402       pending_input_buffers++;
1403       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1404     }
1405     else if(ident == OMX_COMPONENT_GENERATE_EBD)
1406     {
1407       empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1408     }
1409     else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ)
1410     {
1411       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1412     }
1413   }
1414   if(mUseProxyColorFormat) {
1415     if(psource_frame) {
1416       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1417       psource_frame = NULL;
1418     }
1419     while(m_opq_meta_q.m_size) {
1420       unsigned p1,p2,id;
1421       m_opq_meta_q.pop_entry(&p1,&p2,&id);
1422       m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1423          (OMX_BUFFERHEADERTYPE  *)p1);
1424     }
1425     if(pdest_frame){
1426       m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0);
1427       pdest_frame = NULL;
1428     }
1429   }
1430   pthread_mutex_unlock(&m_lock);
1431   /*Check if there are buffers with the Driver*/
1432   if(dev_flush(PORT_INDEX_IN))
1433   {
1434     DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
1435     return false;
1436   }
1437 
1438   return bRet;
1439 }
1440 
1441 
1442 /* ======================================================================
1443 FUNCTION
1444   omx_venc::SendCommandEvent
1445 
1446 DESCRIPTION
1447   Send the event to decoder pipe.  This is needed to generate the callbacks
1448   in decoder thread context.
1449 
1450 PARAMETERS
1451   None.
1452 
1453 RETURN VALUE
1454   true/false
1455 
1456 ========================================================================== */
post_event(unsigned int p1,unsigned int p2,unsigned int id)1457 bool omx_video::post_event(unsigned int p1,
1458                            unsigned int p2,
1459                            unsigned int id)
1460 {
1461   bool bRet      =                      false;
1462 
1463 
1464   pthread_mutex_lock(&m_lock);
1465 
1466   if( id == OMX_COMPONENT_GENERATE_FTB || \
1467       (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
1468   {
1469     m_ftb_q.insert_entry(p1,p2,id);
1470   }
1471   else if((id == m_input_msg_id) \
1472           || (id == OMX_COMPONENT_GENERATE_EBD))
1473   {
1474     m_etb_q.insert_entry(p1,p2,id);
1475   }
1476   else
1477   {
1478     m_cmd_q.insert_entry(p1,p2,id);
1479   }
1480 
1481   bRet = true;
1482   DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
1483   post_message(this, id);
1484   pthread_mutex_unlock(&m_lock);
1485 
1486   return bRet;
1487 }
1488 
1489 /* ======================================================================
1490 FUNCTION
1491   omx_venc::GetParameter
1492 
1493 DESCRIPTION
1494   OMX Get Parameter method implementation
1495 
1496 PARAMETERS
1497   <TBD>.
1498 
1499 RETURN VALUE
1500   Error None if successful.
1501 
1502 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)1503 OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
1504                                         OMX_IN OMX_INDEXTYPE paramIndex,
1505                                         OMX_INOUT OMX_PTR     paramData)
1506 {
1507   OMX_ERRORTYPE eRet = OMX_ErrorNone;
1508   unsigned int height=0,width = 0;
1509 
1510   DEBUG_PRINT_LOW("get_parameter: \n");
1511   if(m_state == OMX_StateInvalid)
1512   {
1513     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
1514     return OMX_ErrorInvalidState;
1515   }
1516   if(paramData == NULL)
1517   {
1518     DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
1519     return OMX_ErrorBadParameter;
1520   }
1521   switch(paramIndex)
1522   {
1523   case OMX_IndexParamPortDefinition:
1524     {
1525       OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1526       portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1527 
1528       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
1529       if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1530       {
1531         DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
1532             m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
1533             m_sInPortDef.nBufferCountActual);
1534         memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
1535 #ifdef _ANDROID_ICS_
1536         if(meta_mode_enable)
1537         {
1538           portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
1539         }
1540         if(secure_session) {
1541           portDefn->format.video.eColorFormat =
1542             (OMX_COLOR_FORMATTYPE)secure_color_format;
1543         }
1544         else if (mUseProxyColorFormat) {
1545             portDefn->format.video.eColorFormat =
1546               (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1547         }
1548 #endif
1549       }
1550       else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1551       {
1552         dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
1553                          &m_sOutPortDef.nBufferCountActual,
1554                          &m_sOutPortDef.nBufferSize,
1555                          m_sOutPortDef.nPortIndex);
1556         DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
1557             m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
1558             m_sOutPortDef.nBufferCountActual);
1559         memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
1560       }
1561       else
1562       {
1563         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1564         eRet = OMX_ErrorBadPortIndex;
1565       }
1566       break;
1567     }
1568   case OMX_IndexParamVideoInit:
1569     {
1570       OMX_PORT_PARAM_TYPE *portParamType =
1571       (OMX_PORT_PARAM_TYPE *) paramData;
1572       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
1573 
1574       memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
1575       break;
1576     }
1577   case OMX_IndexParamVideoPortFormat:
1578     {
1579       OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
1580       (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1581       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
1582 
1583       if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1584       {
1585           int index = portFmt->nIndex;
1586 
1587           if (index > 1) {
1588               eRet = OMX_ErrorNoMore;
1589           } else {
1590               memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
1591 #ifdef _ANDROID_ICS_
1592               if (index == 1) {
1593                   //we support two formats
1594                   //index 0 - YUV420SP
1595                   //index 1 - opaque which internally maps to YUV420SP.
1596                   //this can be extended in the future
1597                   portFmt->nIndex = index; //restore index set from client
1598                   portFmt->eColorFormat =
1599                     (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1600               }
1601           }
1602 #endif
1603       }
1604       else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1605       {
1606         memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
1607       }
1608       else
1609       {
1610         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1611         eRet = OMX_ErrorBadPortIndex;
1612       }
1613       break;
1614     }
1615   case OMX_IndexParamVideoBitrate:
1616     {
1617       OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1618       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
1619 
1620       if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1621       {
1622         memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
1623       }
1624       else
1625       {
1626         DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1627         eRet = OMX_ErrorBadPortIndex;
1628       }
1629 
1630       break;
1631     }
1632   case OMX_IndexParamVideoMpeg4:
1633     {
1634       OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1635       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
1636       memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
1637       break;
1638     }
1639   case OMX_IndexParamVideoH263:
1640     {
1641       OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1642       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
1643       memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
1644       break;
1645     }
1646   case OMX_IndexParamVideoAvc:
1647     {
1648       OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1649       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
1650       memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
1651       break;
1652     }
1653   case OMX_IndexParamVideoProfileLevelQuerySupported:
1654     {
1655       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1656       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
1657       eRet = get_supported_profile_level(pParam);
1658       if(eRet)
1659         DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
1660                           pParam->eProfile, pParam->eLevel);
1661       break;
1662      }
1663   case OMX_IndexParamVideoProfileLevelCurrent:
1664     {
1665       OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1666       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
1667       memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
1668       break;
1669     }
1670     /*Component should support this port definition*/
1671   case OMX_IndexParamAudioInit:
1672     {
1673       OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1674       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
1675       memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
1676       break;
1677     }
1678     /*Component should support this port definition*/
1679   case OMX_IndexParamImageInit:
1680     {
1681       OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1682       DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
1683       memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
1684       break;
1685 
1686     }
1687     /*Component should support this port definition*/
1688   case OMX_IndexParamOtherInit:
1689     {
1690       DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
1691       eRet =OMX_ErrorUnsupportedIndex;
1692       break;
1693     }
1694   case OMX_IndexParamStandardComponentRole:
1695     {
1696       OMX_PARAM_COMPONENTROLETYPE *comp_role;
1697       comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1698       comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
1699       comp_role->nSize = sizeof(*comp_role);
1700 
1701       DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
1702       strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
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_QcomIndexParamVideoMetaBufferMode;
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 = sizeof(meta_buffers[index]);
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,0);
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          = m_sOutPortDef.nBufferSize;
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 && ((OMX_U32)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         m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4071         return OMX_ErrorBadParameter;
4072       }
4073     }
4074   } else if(m_pCallbacks.EmptyBufferDone) {
4075     m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4076   }
4077   return OMX_ErrorNone;
4078 }
4079 
complete_pending_buffer_done_cbs()4080 void omx_video::complete_pending_buffer_done_cbs()
4081 {
4082   unsigned p1;
4083   unsigned p2;
4084   unsigned ident;
4085   omx_cmd_queue tmp_q, pending_bd_q;
4086   pthread_mutex_lock(&m_lock);
4087   // pop all pending GENERATE FDB from ftb queue
4088   while (m_ftb_q.m_size)
4089   {
4090     m_ftb_q.pop_entry(&p1,&p2,&ident);
4091     if(ident == OMX_COMPONENT_GENERATE_FBD)
4092     {
4093       pending_bd_q.insert_entry(p1,p2,ident);
4094     }
4095     else
4096     {
4097       tmp_q.insert_entry(p1,p2,ident);
4098     }
4099   }
4100   //return all non GENERATE FDB to ftb queue
4101   while(tmp_q.m_size)
4102   {
4103     tmp_q.pop_entry(&p1,&p2,&ident);
4104     m_ftb_q.insert_entry(p1,p2,ident);
4105   }
4106   // pop all pending GENERATE EDB from etb queue
4107   while (m_etb_q.m_size)
4108   {
4109     m_etb_q.pop_entry(&p1,&p2,&ident);
4110     if(ident == OMX_COMPONENT_GENERATE_EBD)
4111     {
4112       pending_bd_q.insert_entry(p1,p2,ident);
4113     }
4114     else
4115     {
4116       tmp_q.insert_entry(p1,p2,ident);
4117     }
4118   }
4119   //return all non GENERATE FDB to etb queue
4120   while(tmp_q.m_size)
4121   {
4122     tmp_q.pop_entry(&p1,&p2,&ident);
4123     m_etb_q.insert_entry(p1,p2,ident);
4124   }
4125   pthread_mutex_unlock(&m_lock);
4126   // process all pending buffer dones
4127   while(pending_bd_q.m_size)
4128   {
4129     pending_bd_q.pop_entry(&p1,&p2,&ident);
4130     switch(ident)
4131     {
4132     case OMX_COMPONENT_GENERATE_EBD:
4133         if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
4134         {
4135           DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
4136           omx_report_error ();
4137         }
4138         break;
4139 
4140       case OMX_COMPONENT_GENERATE_FBD:
4141         if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
4142         {
4143           DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
4144           omx_report_error ();
4145         }
4146         break;
4147     }
4148   }
4149 }
4150 
4151 #ifdef MAX_RES_720P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4152 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4153 {
4154   OMX_ERRORTYPE eRet = OMX_ErrorNone;
4155   if(!profileLevelType)
4156     return OMX_ErrorBadParameter;
4157 
4158   if(profileLevelType->nPortIndex == 1) {
4159     if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4160     {
4161       if (profileLevelType->nProfileIndex == 0)
4162       {
4163         profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4164         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4165       }
4166       else if (profileLevelType->nProfileIndex == 1)
4167       {
4168         profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4169         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4170       }
4171       else if(profileLevelType->nProfileIndex == 2)
4172       {
4173         profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4174         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4175       }
4176       else
4177       {
4178         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4179             profileLevelType->nProfileIndex);
4180         eRet = OMX_ErrorNoMore;
4181       }
4182     }
4183     else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4184     {
4185       if (profileLevelType->nProfileIndex == 0)
4186       {
4187         profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4188         profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4189       }
4190       else
4191       {
4192         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4193         eRet = OMX_ErrorNoMore;
4194       }
4195     }
4196     else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4197     {
4198       if (profileLevelType->nProfileIndex == 0)
4199       {
4200         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4201         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4202       }
4203       else if(profileLevelType->nProfileIndex == 1)
4204       {
4205         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4206         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4207       }
4208       else
4209       {
4210         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4211         eRet = OMX_ErrorNoMore;
4212       }
4213     }
4214   }
4215   else
4216   {
4217     DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4218     eRet = OMX_ErrorBadPortIndex;
4219   }
4220   DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4221                     profileLevelType->eProfile,profileLevelType->eLevel);
4222   return eRet;
4223 }
4224 #endif
4225 
4226 #ifdef MAX_RES_1080P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4227 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4228 {
4229   OMX_ERRORTYPE eRet = OMX_ErrorNone;
4230   if(!profileLevelType)
4231     return OMX_ErrorBadParameter;
4232 
4233   if(profileLevelType->nPortIndex == 1) {
4234     if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4235     {
4236       if (profileLevelType->nProfileIndex == 0)
4237       {
4238         profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4239         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4240 
4241       }
4242       else if (profileLevelType->nProfileIndex == 1)
4243       {
4244         profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4245         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4246       }
4247       else if(profileLevelType->nProfileIndex == 2)
4248       {
4249         profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4250         profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4251       }
4252       else
4253       {
4254         DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4255             profileLevelType->nProfileIndex);
4256         eRet = OMX_ErrorNoMore;
4257       }
4258     }
4259     else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4260     {
4261       if (profileLevelType->nProfileIndex == 0)
4262       {
4263         profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4264         profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4265       }
4266       else
4267       {
4268         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4269         eRet = OMX_ErrorNoMore;
4270       }
4271     }
4272     else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4273     {
4274       if (profileLevelType->nProfileIndex == 0)
4275       {
4276         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4277         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4278       }
4279       else if(profileLevelType->nProfileIndex == 1)
4280       {
4281         profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4282         profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4283       }
4284       else
4285       {
4286         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4287         eRet = OMX_ErrorNoMore;
4288       }
4289     }
4290   }
4291   else
4292   {
4293     DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4294     eRet = OMX_ErrorBadPortIndex;
4295   }
4296   DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4297                     profileLevelType->eProfile,profileLevelType->eLevel);
4298   return eRet;
4299 }
4300 
4301 #ifdef USE_ION
alloc_map_ion_memory(int size,struct ion_allocation_data * alloc_data,struct ion_fd_data * fd_data,int flag)4302 int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
4303                                     struct ion_fd_data *fd_data,int flag)
4304 {
4305   struct venc_ion buf_ion_info;
4306   int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
4307   if (size <=0 || !alloc_data || !fd_data) {
4308     DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory");
4309     return -EINVAL;
4310 	}
4311     ion_dev_flags = O_RDONLY;
4312         ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
4313         if(ion_device_fd < 0)
4314         {
4315            DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
4316            return ion_device_fd;
4317         }
4318         alloc_data->len = size;
4319         alloc_data->align = 4096;
4320         alloc_data->flags = 0;
4321         if(!secure_session && (flag & ION_FLAG_CACHED))
4322         {
4323           alloc_data->flags = ION_FLAG_CACHED;
4324         }
4325 
4326         if (secure_session)
4327            alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
4328         else
4329            alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
4330                 ION_HEAP(ION_IOMMU_HEAP_ID));
4331 
4332         rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
4333         if(rc || !alloc_data->handle) {
4334            DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
4335            alloc_data->handle =NULL;
4336            close(ion_device_fd);
4337            ion_device_fd = -1;
4338            return ion_device_fd;
4339         }
4340         fd_data->handle = alloc_data->handle;
4341         rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
4342         if(rc) {
4343             DEBUG_PRINT_ERROR("\n ION MAP failed ");
4344             buf_ion_info.ion_alloc_data = *alloc_data;
4345             buf_ion_info.ion_device_fd = ion_device_fd;
4346             buf_ion_info.fd_ion_data = *fd_data;
4347             free_ion_memory(&buf_ion_info);
4348             fd_data->fd =-1;
4349             ion_device_fd =-1;
4350         }
4351         return ion_device_fd;
4352 }
4353 
free_ion_memory(struct venc_ion * buf_ion_info)4354 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
4355 {
4356      if (!buf_ion_info) {
4357         DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory");
4358         return;
4359      }
4360      if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
4361               &buf_ion_info->ion_alloc_data.handle)) {
4362          DEBUG_PRINT_ERROR("\n ION free failed ");
4363          return;
4364      }
4365      close(buf_ion_info->ion_device_fd);
4366      buf_ion_info->ion_alloc_data.handle = NULL;
4367      buf_ion_info->ion_device_fd = -1;
4368      buf_ion_info->fd_ion_data.fd = -1;
4369 }
4370 #endif
4371 #endif
4372 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)4373 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
4374 {
4375   if(buffer && meta_mode_enable)
4376   {
4377     encoder_media_buffer_type *media_ptr;
4378     struct pmem Input_pmem;
4379     unsigned int index_pmem = 0;
4380     bool meta_error = false;
4381 
4382     index_pmem = (buffer - m_inp_mem_ptr);
4383     if(mUseProxyColorFormat &&
4384        (index_pmem < m_sInPortDef.nBufferCountActual)) {
4385         if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){
4386           DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed");
4387         }
4388     } else {
4389       media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
4390       if(media_ptr && media_ptr->meta_handle)
4391       {
4392         if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
4393            media_ptr->meta_handle->numFds == 1 &&
4394            media_ptr->meta_handle->numInts == 2) {
4395           Input_pmem.fd = media_ptr->meta_handle->data[0];
4396           Input_pmem.buffer = media_ptr;
4397           Input_pmem.size = media_ptr->meta_handle->data[2];
4398           Input_pmem.offset = media_ptr->meta_handle->data[1];
4399           DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
4400                             Input_pmem.offset,
4401                             Input_pmem.size);
4402         } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
4403           private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
4404           Input_pmem.buffer = media_ptr;
4405           Input_pmem.fd = handle->fd;
4406           Input_pmem.offset = 0;
4407           Input_pmem.size = handle->size;
4408         } else {
4409           meta_error = true;
4410           DEBUG_PRINT_ERROR(" Meta Error set in EBD");
4411         }
4412         if(!meta_error)
4413            meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
4414           if(meta_error)
4415           {
4416            DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
4417                input_flush_progress);
4418           }
4419         }
4420      }
4421   }
4422 }
4423 #endif
omx_c2d_conv()4424 omx_video::omx_c2d_conv::omx_c2d_conv()
4425 {
4426   c2dcc = NULL;
4427   mLibHandle = NULL;
4428   mConvertOpen = NULL;
4429   mConvertClose = NULL;
4430   src_format = NV12_2K;
4431 }
4432 
init()4433 bool omx_video::omx_c2d_conv::init() {
4434   bool status = true;
4435   if(mLibHandle || mConvertOpen || mConvertClose) {
4436     DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice");
4437     status = false;
4438   }
4439   if(status) {
4440     mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
4441     if(mLibHandle){
4442        mConvertOpen = (createC2DColorConverter_t *)
4443        dlsym(mLibHandle,"createC2DColorConverter");
4444        mConvertClose = (destroyC2DColorConverter_t *)
4445        dlsym(mLibHandle,"destroyC2DColorConverter");
4446        if(!mConvertOpen || !mConvertClose)
4447          status = false;
4448     } else
4449       status = false;
4450   }
4451   if(!status && mLibHandle){
4452     dlclose(mLibHandle);
4453     mLibHandle = NULL;
4454     mConvertOpen = NULL;
4455     mConvertClose = NULL;
4456   }
4457   return status;
4458 }
4459 
convert(int src_fd,void * src_base,void * src_viraddr,int dest_fd,void * dest_base,void * dest_viraddr)4460 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr,
4461      int dest_fd, void *dest_base, void *dest_viraddr)
4462 {
4463   int result;
4464   if(!src_viraddr || !dest_viraddr || !c2dcc){
4465     DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert");
4466     return false;
4467   }
4468   result =  c2dcc->convertC2D(src_fd, src_base, src_viraddr,
4469                               dest_fd, dest_base, dest_viraddr);
4470   DEBUG_PRINT_LOW("\n Color convert status %d",result);
4471   return ((result < 0)?false:true);
4472 }
4473 
open(unsigned int height,unsigned int width,ColorConvertFormat src,ColorConvertFormat dest,unsigned int srcStride)4474 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
4475      ColorConvertFormat src, ColorConvertFormat dest,
4476      unsigned int srcStride)
4477 {
4478   bool status = false;
4479   if(!c2dcc) {
4480      c2dcc = mConvertOpen(width, height, width, height,
4481              src, dest, 0, srcStride);
4482      if(c2dcc) {
4483        src_format = src;
4484        status = true;
4485      } else
4486        DEBUG_PRINT_ERROR("\n mConvertOpen failed");
4487   }
4488    return status;
4489 }
close()4490 void omx_video::omx_c2d_conv::close()
4491 {
4492   if(mLibHandle) {
4493     if(mConvertClose && c2dcc)
4494      mConvertClose(c2dcc);
4495     c2dcc = NULL;
4496   }
4497 }
~omx_c2d_conv()4498 omx_video::omx_c2d_conv::~omx_c2d_conv()
4499 {
4500   DEBUG_PRINT_ERROR("\n Destroy C2D instance");
4501   if(mLibHandle) {
4502     if(mConvertClose && c2dcc)
4503       mConvertClose(c2dcc);
4504     dlclose(mLibHandle);
4505   }
4506   c2dcc = NULL;
4507   mLibHandle = NULL;
4508   mConvertOpen = NULL;
4509   mConvertClose = NULL;
4510 }
get_src_format()4511 int omx_video::omx_c2d_conv::get_src_format()
4512 {
4513   int format = -1;
4514   if(src_format == NV12_2K) {
4515     format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
4516   } else if(src_format == RGBA8888) {
4517     format = HAL_PIXEL_FORMAT_RGBA_8888;
4518   }
4519   return format;
4520 }
get_buffer_size(int port,unsigned int & buf_size)4521 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
4522 {
4523   int cret = 0;
4524   bool ret = false;
4525   C2DBuffReq bufferreq;
4526   if(c2dcc){
4527     bufferreq.size = 0;
4528     cret = c2dcc->getBuffReq(port,&bufferreq);
4529     DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret);
4530     ret = (cret)?false:true;
4531     buf_size = bufferreq.size;
4532   }
4533   return ret;
4534 }
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4535 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
4536                                                   OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4537 {
4538   unsigned nBufIndex = 0;
4539   OMX_ERRORTYPE ret = OMX_ErrorNone;
4540   encoder_media_buffer_type *media_buffer;
4541   DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer);
4542 
4543   if(buffer == NULL) {
4544     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer);
4545     return OMX_ErrorBadParameter;
4546   }
4547   nBufIndex = buffer - meta_buffer_hdr;
4548   if(nBufIndex >= m_sInPortDef.nBufferCountActual) {
4549     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n",
4550                       nBufIndex);
4551     return OMX_ErrorBadParameter;
4552   }
4553   media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
4554   private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4555   /*Enable following code once private handle color format is
4556     updated correctly*/
4557 
4558   if(buffer->nFilledLen > 0) {
4559     if(c2d_opened && handle->format != c2d_conv.get_src_format()) {
4560       c2d_conv.close();
4561       c2d_opened = false;
4562     }
4563     if (!c2d_opened) {
4564         if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
4565           DEBUG_PRINT_ERROR("\n open Color conv for RGBA888");
4566           if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
4567                m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K,
4568                (unsigned int)handle->width)){
4569              m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4570              DEBUG_PRINT_ERROR("\n Color conv open failed");
4571              return OMX_ErrorBadParameter;
4572           }
4573           c2d_opened = true;
4574         } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
4575           DEBUG_PRINT_ERROR("\n Incorrect color format");
4576           m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4577           return OMX_ErrorBadParameter;
4578         }
4579     }
4580   }
4581 
4582   if(input_flush_progress == true)
4583   {
4584     m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4585     DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress");
4586     return OMX_ErrorNone;
4587   }
4588 
4589   if(!psource_frame) {
4590     psource_frame = buffer;
4591     ret = push_input_buffer(hComp);
4592   } else {
4593     if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) {
4594       m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4595       DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full");
4596       ret = OMX_ErrorBadParameter;
4597     }
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   } else {
4631     // there has been an error and source frame has been scheduled for an EBD
4632     psource_frame = NULL;
4633   }
4634   return ret;
4635 }
4636 
convert_queue_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info,unsigned & index)4637 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
4638      struct pmem &Input_pmem_info,unsigned &index){
4639 
4640   unsigned char *uva;
4641   OMX_ERRORTYPE ret = OMX_ErrorNone;
4642   unsigned address = 0,p2,id;
4643 
4644   DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer");
4645   if(!psource_frame || !pdest_frame) {
4646     DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4647     return OMX_ErrorBadParameter;
4648   }
4649 
4650   if(!psource_frame->nFilledLen){
4651     if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){
4652         pdest_frame->nFilledLen = psource_frame->nFilledLen;
4653         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4654         pdest_frame->nFlags = psource_frame->nFlags;
4655         DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \
4656           Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen);
4657     } else {
4658         pdest_frame->nOffset = 0;
4659         pdest_frame->nFilledLen = 0;
4660         pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4661         pdest_frame->nFlags = psource_frame->nFlags;
4662         DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4663            pdest_frame,pdest_frame->nFilledLen);
4664     }
4665   } else {
4666      uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
4667                            PROT_READ|PROT_WRITE,
4668                            MAP_SHARED,Input_pmem_info.fd,0);
4669      if(uva == MAP_FAILED) {
4670        ret = OMX_ErrorBadParameter;
4671      } else {
4672        if(!c2d_conv.convert(Input_pmem_info.fd, uva, uva,
4673           m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) {
4674           DEBUG_PRINT_ERROR("\n Color Conversion failed");
4675           ret = OMX_ErrorBadParameter;
4676        } else {
4677           unsigned int buf_size = 0;
4678           if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
4679             ret = OMX_ErrorBadParameter;
4680           else {
4681             pdest_frame->nOffset = 0;
4682             if(!buf_size || buf_size > pdest_frame->nAllocLen) {
4683               DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer"
4684                "size mismatch buf size %d alloc size %d",
4685                       buf_size, pdest_frame->nAllocLen);
4686               ret = OMX_ErrorBadParameter;
4687               buf_size = 0;
4688             }
4689             pdest_frame->nFilledLen = buf_size;
4690             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4691             pdest_frame->nFlags = psource_frame->nFlags;
4692             DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4693                pdest_frame,pdest_frame->nFilledLen);
4694            }
4695          }
4696          munmap(uva,Input_pmem_info.size);
4697       }
4698     }
4699     if((ret == OMX_ErrorNone) &&
4700        dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
4701       DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4702       post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
4703       ret = OMX_ErrorBadParameter;
4704     }
4705     if(ret == OMX_ErrorNone)
4706       ret = empty_this_buffer_proxy(hComp,pdest_frame);
4707     if(ret == OMX_ErrorNone) {
4708       m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
4709       psource_frame = NULL;
4710       pdest_frame = NULL;
4711       if(!psource_frame && m_opq_meta_q.m_size) {
4712         m_opq_meta_q.pop_entry(&address,&p2,&id);
4713         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4714       }
4715       if(!pdest_frame && m_opq_pmem_q.m_size) {
4716         m_opq_pmem_q.pop_entry(&address,&p2,&id);
4717         pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4718         DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame);
4719       }
4720     } else {
4721       // there has been an error and source frame has been scheduled for an EBD
4722       psource_frame = NULL;
4723     }
4724     return ret;
4725 }
4726 
push_input_buffer(OMX_HANDLETYPE hComp)4727 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
4728 {
4729   unsigned address = 0,p2,id, index = 0;
4730   OMX_ERRORTYPE ret = OMX_ErrorNone;
4731 
4732   if(!psource_frame && m_opq_meta_q.m_size) {
4733     m_opq_meta_q.pop_entry(&address,&p2,&id);
4734     psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4735   }
4736   if(!pdest_frame && m_opq_pmem_q.m_size) {
4737     m_opq_pmem_q.pop_entry(&address,&p2,&id);
4738     pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4739   }
4740   while(psource_frame != NULL && pdest_frame != NULL &&
4741         ret == OMX_ErrorNone) {
4742     struct pmem Input_pmem_info;
4743     encoder_media_buffer_type *media_buffer;
4744     index = pdest_frame - m_inp_mem_ptr;
4745     if(index >= m_sInPortDef.nBufferCountActual){
4746        DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d",
4747                          index,m_sInPortDef.nBufferCountActual);
4748        return OMX_ErrorBadParameter;
4749     }
4750     media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
4751     /*Will enable to verify camcorder in current TIPS can be removed*/
4752     if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
4753       Input_pmem_info.buffer = media_buffer;
4754       Input_pmem_info.fd = media_buffer->meta_handle->data[0];
4755       Input_pmem_info.offset = media_buffer->meta_handle->data[1];
4756       Input_pmem_info.size = media_buffer->meta_handle->data[2];
4757       DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
4758                         Input_pmem_info.offset,
4759                         Input_pmem_info.size);
4760       ret = queue_meta_buffer(hComp,Input_pmem_info);
4761     } else if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) {
4762        ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4763     } else {
4764       private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4765       Input_pmem_info.buffer = media_buffer;
4766       Input_pmem_info.fd = handle->fd;
4767       Input_pmem_info.offset = 0;
4768       Input_pmem_info.size = handle->size;
4769       if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
4770         ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4771       else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
4772         ret = queue_meta_buffer(hComp,Input_pmem_info);
4773       else
4774         ret = OMX_ErrorBadParameter;
4775     }
4776    }
4777   return ret;
4778 }
4779