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