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