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