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