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