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