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