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