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