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