• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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                         return OMX_ErrorInsufficientResources;
3700                     }
3701                     (*bufferHdr)->nAllocLen = sizeof(output_metabuffer);
3702                     handle->data[0] = m_pOutput_pmem[i].fd;
3703                     handle->data[1] = 0;
3704                     handle->data[2] = 0;
3705                     handle->data[3] = ALIGN(m_sOutPortDef.nBufferSize, 4096);
3706                     output_metabuffer *buffer = (output_metabuffer*) m_pOutput_pmem[i].buffer;
3707                     buffer->type = 1;
3708                     buffer->nh = handle;
3709                 }
3710             }
3711 
3712             (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
3713             (*bufferHdr)->pAppPrivate = appData;
3714 
3715             BITMASK_SET(&m_out_bm_count,i);
3716 
3717             if (dev_use_buf(PORT_INDEX_OUT) != true) {
3718                 DEBUG_PRINT_ERROR("ERROR: dev_use_buf FAILED for o/p buf");
3719                 return OMX_ErrorInsufficientResources;
3720             }
3721         } else {
3722             DEBUG_PRINT_ERROR("ERROR: All o/p buffers are allocated, invalid allocate buf call"
3723                     "for index [%d] actual: %u", i, (unsigned int)m_sOutPortDef.nBufferCountActual);
3724         }
3725     }
3726 
3727     return eRet;
3728 }
3729 
3730 
3731 // AllocateBuffer  -- API Call
3732 /* ======================================================================
3733    FUNCTION
3734    omx_video::AllocateBuffer
3735 
3736    DESCRIPTION
3737    Returns zero if all the buffers released..
3738 
3739    PARAMETERS
3740    None.
3741 
3742    RETURN VALUE
3743    true/false
3744 
3745    ========================================================================== */
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)3746 OMX_ERRORTYPE  omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
3747         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3748         OMX_IN OMX_U32                        port,
3749         OMX_IN OMX_PTR                     appData,
3750         OMX_IN OMX_U32                       bytes)
3751 {
3752 
3753     OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
3754 
3755     DEBUG_PRINT_LOW("Allocate buffer of size = %u on port %d", (unsigned int)bytes, (int)port);
3756     if (m_state == OMX_StateInvalid) {
3757         DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State");
3758         return OMX_ErrorInvalidState;
3759     }
3760      auto_lock l(m_buf_lock);
3761     // What if the client calls again.
3762     if (port == PORT_INDEX_IN) {
3763 #ifdef _ANDROID_ICS_
3764         if (meta_mode_enable)
3765             eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
3766         else
3767 #endif
3768             eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3769     } else if (port == PORT_INDEX_OUT) {
3770         eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3771     } else {
3772         DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d",(int)port);
3773         eRet = OMX_ErrorBadPortIndex;
3774     }
3775     DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
3776     if (eRet == OMX_ErrorNone) {
3777         if (allocate_done()) {
3778             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3779                 // Send the callback now
3780                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3781                 post_event(OMX_CommandStateSet,OMX_StateIdle,
3782                         OMX_COMPONENT_GENERATE_EVENT);
3783             }
3784         }
3785         if (port == PORT_INDEX_IN && m_sInPortDef.bPopulated) {
3786             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
3787                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3788                 post_event(OMX_CommandPortEnable,
3789                         PORT_INDEX_IN,
3790                         OMX_COMPONENT_GENERATE_EVENT);
3791             }
3792         }
3793         if (port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated) {
3794             if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
3795                 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3796                 post_event(OMX_CommandPortEnable,
3797                         PORT_INDEX_OUT,
3798                         OMX_COMPONENT_GENERATE_EVENT);
3799                 m_event_port_settings_sent = false;
3800             }
3801         }
3802     }
3803     DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
3804     return eRet;
3805 }
3806 
3807 
3808 // Free Buffer - API call
3809 /* ======================================================================
3810    FUNCTION
3811    omx_video::FreeBuffer
3812 
3813    DESCRIPTION
3814 
3815    PARAMETERS
3816    None.
3817 
3818    RETURN VALUE
3819    true/false
3820 
3821    ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3822 OMX_ERRORTYPE  omx_video::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
3823         OMX_IN OMX_U32                 port,
3824         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3825 {
3826     (void)hComp;
3827     OMX_ERRORTYPE eRet = OMX_ErrorNone;
3828     unsigned int nPortIndex;
3829 
3830     DEBUG_PRINT_LOW("In for encoder free_buffer");
3831     auto_lock l(m_buf_lock);
3832     if (port == PORT_INDEX_OUT) { //client called freebuffer, clearing client buffer bitmask right away to avoid use after free
3833         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3834         if(BITMASK_PRESENT(&m_client_out_bm_count, nPortIndex))
3835             BITMASK_CLEAR(&m_client_out_bm_count,nPortIndex);
3836     } else if (port == PORT_INDEX_IN) {
3837         nPortIndex = buffer - (meta_mode_enable?meta_buffer_hdr:m_inp_mem_ptr);
3838         if(BITMASK_PRESENT(&m_client_in_bm_count, nPortIndex))
3839             BITMASK_CLEAR(&m_client_in_bm_count,nPortIndex);
3840     }
3841     if (m_state == OMX_StateIdle &&
3842             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3843         DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
3844     } else if ((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
3845             (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT)) {
3846         DEBUG_PRINT_LOW("Free Buffer while port %u disabled", (unsigned int)port);
3847     } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
3848         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled");
3849         m_buffer_freed = true;
3850         post_event(OMX_EventError,
3851                 OMX_ErrorPortUnpopulated,
3852                 OMX_COMPONENT_GENERATE_EVENT);
3853         return eRet;
3854     } else {
3855         DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers");
3856         m_buffer_freed = true;
3857         post_event(OMX_EventError,
3858                 OMX_ErrorPortUnpopulated,
3859                 OMX_COMPONENT_GENERATE_EVENT);
3860     }
3861 
3862     if (port == PORT_INDEX_IN) {
3863         // check if the buffer is valid
3864         nPortIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
3865 
3866         DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %u, actual cnt %u",
3867                 nPortIndex, (unsigned int)m_sInPortDef.nBufferCountActual);
3868         if (nPortIndex < m_sInPortDef.nBufferCountActual &&
3869                 BITMASK_PRESENT(&m_inp_bm_count, nPortIndex)) {
3870             // Clear the bit associated with it.
3871             BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
3872             free_input_buffer (buffer);
3873             m_sInPortDef.bPopulated = OMX_FALSE;
3874 
3875             /*Free the Buffer Header*/
3876             if (release_input_done()) {
3877                 input_use_buffer = false;
3878                 // "m_inp_mem_ptr" may point to "meta_buffer_hdr" in some modes,
3879                 // in which case, it was not explicitly allocated
3880                 if (m_inp_mem_ptr && m_inp_mem_ptr != meta_buffer_hdr) {
3881                     DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr");
3882                     free (m_inp_mem_ptr);
3883                 }
3884                 m_inp_mem_ptr = NULL;
3885                 if (m_pInput_pmem) {
3886                     DEBUG_PRINT_LOW("Freeing m_pInput_pmem");
3887                     free(m_pInput_pmem);
3888                     m_pInput_pmem = NULL;
3889                 }
3890 #ifdef USE_ION
3891                 if (m_pInput_ion) {
3892                     DEBUG_PRINT_LOW("Freeing m_pInput_ion");
3893                     free(m_pInput_ion);
3894                     m_pInput_ion = NULL;
3895                 }
3896 #endif
3897             }
3898         } else {
3899             DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid");
3900             eRet = OMX_ErrorBadPortIndex;
3901         }
3902 
3903         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3904                 && release_input_done()) {
3905             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3906             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3907             post_event(OMX_CommandPortDisable,
3908                     PORT_INDEX_IN,
3909                     OMX_COMPONENT_GENERATE_EVENT);
3910         }
3911     } else if (port == PORT_INDEX_OUT) {
3912         // check if the buffer is valid
3913         nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3914 
3915         DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %u, actual cnt %u",
3916                 nPortIndex, (unsigned int)m_sOutPortDef.nBufferCountActual);
3917         if (nPortIndex < m_sOutPortDef.nBufferCountActual &&
3918                 BITMASK_PRESENT(&m_out_bm_count, nPortIndex)) {
3919             // Clear the bit associated with it.
3920             BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
3921             m_sOutPortDef.bPopulated = OMX_FALSE;
3922             free_output_buffer (buffer);
3923 
3924             if (release_output_done()) {
3925                 output_use_buffer = false;
3926                 if (m_out_mem_ptr) {
3927                     DEBUG_PRINT_LOW("Freeing m_out_mem_ptr");
3928                     free (m_out_mem_ptr);
3929                     m_out_mem_ptr = NULL;
3930                 }
3931                 if (m_pOutput_pmem) {
3932                     DEBUG_PRINT_LOW("Freeing m_pOutput_pmem");
3933                     free(m_pOutput_pmem);
3934                     m_pOutput_pmem = NULL;
3935                 }
3936 #ifdef USE_ION
3937                 if (m_pOutput_ion) {
3938                     DEBUG_PRINT_LOW("Freeing m_pOutput_ion");
3939                     free(m_pOutput_ion);
3940                     m_pOutput_ion = NULL;
3941                 }
3942 #endif
3943             }
3944         } else {
3945             DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid");
3946             eRet = OMX_ErrorBadPortIndex;
3947         }
3948         if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3949                 && release_output_done() ) {
3950             DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
3951 
3952             DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
3953             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3954             post_event(OMX_CommandPortDisable,
3955                     PORT_INDEX_OUT,
3956                     OMX_COMPONENT_GENERATE_EVENT);
3957 
3958         }
3959     } else if (port == PORT_INDEX_EXTRADATA_OUT) {
3960         nPortIndex = buffer - m_client_output_extradata_mem_ptr;
3961         DEBUG_PRINT_LOW("free_buffer on extradata output port - Port idx %d", nPortIndex);
3962 
3963         BITMASK_CLEAR(&m_out_extradata_bm_count,nPortIndex);
3964 
3965         if (release_output_extradata_done()) {
3966             free_output_extradata_buffer_header();
3967         }
3968     } else if (port == PORT_INDEX_EXTRADATA_IN) {
3969         nPortIndex = buffer - m_client_input_extradata_mem_ptr;
3970         DEBUG_PRINT_LOW("free_buffer on extradata input port - Port idx %d", nPortIndex);
3971 
3972         BITMASK_CLEAR(&m_in_extradata_bm_count,nPortIndex);
3973 
3974         if (release_input_extradata_done()) {
3975             free_input_extradata_buffer_header();
3976         }
3977     } else {
3978         eRet = OMX_ErrorBadPortIndex;
3979     }
3980     if ((eRet == OMX_ErrorNone) &&
3981             (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
3982         if (release_done()) {
3983             if (dev_stop() != 0) {
3984                 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED");
3985                 eRet = OMX_ErrorHardware;
3986             }
3987             // Send the callback now
3988             BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3989             post_event(OMX_CommandStateSet, OMX_StateLoaded,
3990                     OMX_COMPONENT_GENERATE_EVENT);
3991         } else {
3992             DEBUG_PRINT_HIGH("in free buffer, release not done, need to free more buffers output %" PRIx64" input %" PRIx64,
3993                     m_out_bm_count, m_inp_bm_count);
3994         }
3995     }
3996     if (eRet != OMX_ErrorNone) {
3997         m_buffer_freed = true;
3998     }
3999 
4000     return eRet;
4001 }
4002 
free_output_extradata_buffer_header()4003 void omx_video::free_output_extradata_buffer_header() {
4004     m_sExtraData = false;
4005     if (m_client_output_extradata_mem_ptr) {
4006         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
4007         free(m_client_output_extradata_mem_ptr);
4008         m_client_output_extradata_mem_ptr = NULL;
4009     }
4010 }
4011 
free_input_extradata_buffer_header()4012 void omx_video::free_input_extradata_buffer_header() {
4013     m_sExtraData = false;
4014     if (m_client_input_extradata_mem_ptr) {
4015         DEBUG_PRINT_LOW("Free extradata pmem Pointer area");
4016         free(m_client_input_extradata_mem_ptr);
4017         m_client_input_extradata_mem_ptr = NULL;
4018     }
4019 }
4020 
4021 /* ======================================================================
4022    FUNCTION
4023    omx_video::EmptyThisBuffer
4024 
4025    DESCRIPTION
4026    This routine is used to push the encoded video frames to
4027    the video decoder.
4028 
4029    PARAMETERS
4030    None.
4031 
4032    RETURN VALUE
4033    OMX Error None if everything went successful.
4034 
4035    ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4036 OMX_ERRORTYPE  omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
4037         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4038 {
4039     if(buffer != NULL && buffer->nInputPortIndex == PORT_INDEX_EXTRADATA_IN) {
4040         if(!dev_handle_client_input_extradata(buffer)) {
4041             DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> handling client extradata failed");
4042             return OMX_ErrorMax;
4043         }
4044         return OMX_ErrorNone;
4045     }
4046     OMX_ERRORTYPE ret1 = OMX_ErrorNone;
4047     unsigned int nBufferIndex ;
4048 
4049     if (m_state != OMX_StateExecuting &&
4050             m_state != OMX_StatePause &&
4051             m_state != OMX_StateIdle) {
4052         DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State");
4053         return OMX_ErrorInvalidState;
4054     }
4055 
4056     if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
4057         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> buffer is null or buffer size is invalid");
4058         return OMX_ErrorBadParameter;
4059     }
4060 
4061     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
4062         DEBUG_PRINT_ERROR("ERROR: omx_video::etb--> OMX Version Invalid");
4063         return OMX_ErrorVersionMismatch;
4064     }
4065 
4066     DEBUG_PRINT_LOW("ETB: buffer = %p, buffer->pBuffer[%p]", buffer, buffer->pBuffer);
4067     if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN) {
4068         DEBUG_PRINT_ERROR("ERROR: Bad port index to call empty_this_buffer");
4069         return OMX_ErrorBadPortIndex;
4070     }
4071     if (!m_sInPortDef.bEnabled) {
4072         DEBUG_PRINT_ERROR("ERROR: Cannot call empty_this_buffer while I/P port is disabled");
4073         return OMX_ErrorIncorrectStateOperation;
4074     }
4075 
4076     nBufferIndex = buffer - ((!meta_mode_enable)?m_inp_mem_ptr:meta_buffer_hdr);
4077 
4078     if (nBufferIndex > m_sInPortDef.nBufferCountActual ) {
4079         DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]", nBufferIndex);
4080         return OMX_ErrorBadParameter;
4081     }
4082 
4083     m_etb_count++;
4084     m_etb_timestamp = buffer->nTimeStamp;
4085     DEBUG_PRINT_LOW("DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
4086     post_event ((unsigned long)hComp,(unsigned long)buffer,m_input_msg_id);
4087     return OMX_ErrorNone;
4088 }
4089 
profile_etb()4090 bool omx_video::profile_etb() {
4091     if (profile_mode) {
4092         struct timeval act_time = {0, 0};
4093         gettimeofday(&act_time, NULL);
4094         if (profile_start_time == 0) {
4095             profile_start_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
4096         } else {
4097             profile_last_time = (act_time.tv_usec + act_time.tv_sec * 1e6);
4098         }
4099         profile_frame_count++;
4100         return true;
4101     }
4102     return false;
4103 }
4104 
4105 /* ======================================================================
4106    FUNCTION
4107    omx_video::empty_this_buffer_proxy
4108 
4109    DESCRIPTION
4110    This routine is used to push the encoded video frames to
4111    the video decoder.
4112 
4113    PARAMETERS
4114    None.
4115 
4116    RETURN VALUE
4117    OMX Error None if everything went successful.
4118 
4119    ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4120 OMX_ERRORTYPE  omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE  hComp,
4121         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4122 {
4123     VIDC_TRACE_NAME_HIGH("ETB");
4124     (void)hComp;
4125     OMX_U8 *pmem_data_buf = NULL;
4126     int push_cnt = 0;
4127     unsigned nBufIndex = 0;
4128     OMX_ERRORTYPE ret = OMX_ErrorNone;
4129     LEGACY_CAM_METADATA_TYPE *media_buffer = NULL;
4130 
4131     int fd = 0;
4132 
4133     DEBUG_PRINT_LOW("ETBProxy: buffer->pBuffer[%p]", buffer->pBuffer);
4134     if (buffer == NULL) {
4135         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid buffer[%p]", buffer);
4136         return OMX_ErrorBadParameter;
4137     }
4138 
4139     if (profile_etb()) {
4140         m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4141         return OMX_ErrorNone;
4142     }
4143 
4144     // Buffer sanity checks
4145     if (meta_mode_enable && !mUsesColorConversion) {
4146         //For color-conversion case, we have an internal buffer and not a meta buffer
4147         bool met_error = false;
4148         nBufIndex = buffer - meta_buffer_hdr;
4149         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
4150             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid meta-bufIndex = %u", nBufIndex);
4151             return OMX_ErrorBadParameter;
4152         }
4153         media_buffer = (LEGACY_CAM_METADATA_TYPE *)meta_buffer_hdr[nBufIndex].pBuffer;
4154         if (!media_buffer) {
4155             DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4156             return OMX_ErrorBadParameter;
4157         }
4158         if ((media_buffer->buffer_type == LEGACY_CAM_SOURCE)
4159                 && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
4160             DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
4161                     buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
4162             met_error = true;
4163         } else if (media_buffer) {
4164             if (media_buffer->buffer_type != LEGACY_CAM_SOURCE &&
4165                     media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
4166                 DEBUG_PRINT_ERROR("Buffer type is neither LEGACY_CAM_SOURCE nor gralloc source");
4167                 met_error = true;
4168             } else {
4169                 if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4170                     if (media_buffer->meta_handle == NULL) {
4171                         DEBUG_PRINT_ERROR("Buffer type is LEGACY_CAM_SOURCE but handle is null");
4172                         met_error = true;
4173                     }
4174                     else {
4175                         // TBD: revisit this check !
4176                         int nFds = media_buffer->meta_handle->numFds,
4177                             nInt = media_buffer->meta_handle->numInts;
4178                         met_error = ((nFds == 1 && nInt >= 2) /*normal*/ ||
4179                                 (nFds < 16 && nInt >= nFds*3) /*batch*/) ? false : true;
4180                         if (met_error) {
4181                             DEBUG_PRINT_ERROR("Unbalanced fds in handle: fds=%d ints=%d",
4182                                     nFds, nInt);
4183                         }
4184                     }
4185                 }
4186             }
4187         } else {
4188             met_error = true;
4189             DEBUG_PRINT_ERROR("Unrecognized camera source type");
4190         }
4191         if (met_error) {
4192             DEBUG_PRINT_ERROR("ERROR: Unkown source/metahandle in ETB call");
4193             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4194             return OMX_ErrorBadParameter;
4195         }
4196     } else {
4197         nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
4198         if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
4199             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Invalid bufIndex = %u", nBufIndex);
4200             return OMX_ErrorBadParameter;
4201         }
4202     }
4203 
4204     if (buffer->nFilledLen == 0 && (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
4205         DEBUG_PRINT_LOW("Zero length EOS buffer");
4206         handle_empty_eos_buffer();
4207         post_event ((unsigned long)buffer,0,
4208                 OMX_COMPONENT_GENERATE_EBD);
4209         return OMX_ErrorNone;
4210     }
4211 
4212     pending_input_buffers++;
4213     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4214     if (input_flush_progress == true) {
4215         post_event ((unsigned long)buffer,0,
4216                 OMX_COMPONENT_GENERATE_EBD);
4217         DEBUG_PRINT_ERROR("ERROR: ETBProxy: Input flush in progress");
4218         return OMX_ErrorNone;
4219     }
4220     if (!meta_mode_enable) {
4221         fd = m_pInput_pmem[nBufIndex].fd;
4222     }
4223 #ifdef _ANDROID_ICS_
4224     if (meta_mode_enable && !mUsesColorConversion) {
4225         // Camera or Gralloc-source meta-buffers queued with encodeable color-format
4226         struct pmem Input_pmem_info;
4227         if (!media_buffer) {
4228             DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
4229             return OMX_ErrorBadParameter;
4230         }
4231         if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
4232             Input_pmem_info.buffer = media_buffer;
4233             Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
4234             fd = Input_pmem_info.fd;
4235 
4236             int offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
4237             int size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
4238             if (offset < 0 || size < 0) {
4239                 DEBUG_PRINT_ERROR("meta-buffer is invalid!");
4240                 return OMX_ErrorBadParameter;
4241             }
4242             Input_pmem_info.offset = offset;
4243             Input_pmem_info.size = size;
4244             DEBUG_PRINT_HIGH("ETB (meta-Camera) fd = %d, offset = %d, size = %d",
4245                     Input_pmem_info.fd, Input_pmem_info.offset,
4246                     Input_pmem_info.size);
4247         } else {
4248             VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)meta_buffer_hdr[nBufIndex].pBuffer;
4249             private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
4250             Input_pmem_info.buffer = media_buffer;
4251             Input_pmem_info.fd = handle->fd;
4252             fd = Input_pmem_info.fd;
4253             Input_pmem_info.offset = 0;
4254             Input_pmem_info.size = handle->size;
4255             DEBUG_PRINT_LOW("ETB (meta-gralloc) fd = %d, offset = %d, size = %d",
4256                     Input_pmem_info.fd, Input_pmem_info.offset,
4257                     Input_pmem_info.size);
4258             // if input buffer dimensions is different from what is configured,
4259             // reject the buffer
4260             if (ALIGN((int)m_sInPortDef.format.video.nFrameWidth,32) != ALIGN(handle->unaligned_width,32) ||
4261                     ALIGN((int)m_sInPortDef.format.video.nFrameHeight,32) != ALIGN(handle->unaligned_height,32)) {
4262                 ALOGE("Graphic buf size(%dx%d) does not match configured size(%ux%u)",
4263                         handle->unaligned_width, handle->unaligned_height,
4264                         m_sInPortDef.format.video.nFrameWidth, m_sInPortDef.format.video.nFrameHeight);
4265                 post_event ((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4266                 return OMX_ErrorNone;
4267             }
4268         }
4269         if (dev_use_buf(PORT_INDEX_IN) != true) {
4270             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
4271             post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4272             return OMX_ErrorBadParameter;
4273         }
4274     } else if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4275 #else
4276     if (input_use_buffer && !m_use_input_pmem && m_pInput_pmem[nBufIndex].buffer)
4277 #endif
4278     {
4279         DEBUG_PRINT_LOW("Heap UseBuffer case, so memcpy the data");
4280 
4281         auto_lock l(m_buf_lock);
4282         pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
4283         if (pmem_data_buf && BITMASK_PRESENT(&m_client_in_bm_count, nBufIndex)) {
4284             memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
4285                     buffer->nFilledLen);
4286         }
4287         DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
4288     } else if (mUseProxyColorFormat) {
4289         // Gralloc-source buffers with color-conversion
4290         fd = m_pInput_pmem[nBufIndex].fd;
4291         DEBUG_PRINT_LOW("ETB (color-converted) fd = %d, size = %u",
4292                 fd, (unsigned int)buffer->nFilledLen);
4293     } else if (m_sInPortDef.format.video.eColorFormat ==
4294                     OMX_COLOR_FormatYUV420SemiPlanar) {
4295             //For the case where YUV420SP buffers are qeueued to component
4296             //by sources other than camera (Apps via MediaCodec), conversion
4297             //to vendor flavoured NV12 color format is required.
4298             if (!dev_color_align(buffer, m_sInPortDef.format.video.nFrameWidth,
4299                                     m_sInPortDef.format.video.nFrameHeight)) {
4300                     DEBUG_PRINT_ERROR("Failed to adjust buffer color");
4301                     post_event((unsigned long)buffer, 0, OMX_COMPONENT_GENERATE_EBD);
4302                     return OMX_ErrorUndefined;
4303             }
4304     }
4305     if (dev_empty_buf(buffer, pmem_data_buf,nBufIndex,fd) != true)
4306     {
4307         DEBUG_PRINT_ERROR("ERROR: ETBProxy: dev_empty_buf failed");
4308 #ifdef _ANDROID_ICS_
4309         omx_release_meta_buffer(buffer);
4310 #endif
4311         post_event ((unsigned long)buffer,0,OMX_COMPONENT_GENERATE_EBD);
4312         /*Generate an async error and move to invalid state*/
4313         pending_input_buffers--;
4314         VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4315         if (hw_overload) {
4316             return OMX_ErrorInsufficientResources;
4317         }
4318         return OMX_ErrorBadParameter;
4319     }
4320     return ret;
4321 }
4322 
4323 /* ======================================================================
4324    FUNCTION
4325    omx_video::FillThisBuffer
4326 
4327    DESCRIPTION
4328    IL client uses this method to release the frame buffer
4329    after displaying them.
4330 
4331    PARAMETERS
4332    None.
4333 
4334    RETURN VALUE
4335    true/false
4336 
4337    ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4338 OMX_ERRORTYPE  omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
4339         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4340 {
4341    if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE))) {
4342       DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size");
4343       return OMX_ErrorBadParameter;
4344     }
4345 
4346     DEBUG_PRINT_LOW("FTB: buffer->pBuffer[%p]", buffer->pBuffer);
4347 
4348     if (m_state != OMX_StateExecuting &&
4349             m_state != OMX_StatePause &&
4350             m_state != OMX_StateIdle) {
4351         DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State");
4352         return OMX_ErrorInvalidState;
4353     }
4354 
4355     if (buffer->nOutputPortIndex == PORT_INDEX_EXTRADATA_OUT) {
4356         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->invalid port in header");
4357         return OMX_ErrorBadParameter;
4358     }
4359 
4360     if (buffer->nVersion.nVersion != OMX_SPEC_VERSION) {
4361         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid");
4362         return OMX_ErrorVersionMismatch;
4363     }
4364 
4365     if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT) {
4366         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index");
4367         return OMX_ErrorBadPortIndex;
4368     }
4369 
4370     if (!m_sOutPortDef.bEnabled) {
4371         DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled");
4372         return OMX_ErrorIncorrectStateOperation;
4373     }
4374 
4375     post_event((unsigned long) hComp, (unsigned long)buffer,OMX_COMPONENT_GENERATE_FTB);
4376     return OMX_ErrorNone;
4377 }
4378 
4379 /* ======================================================================
4380    FUNCTION
4381    omx_video::fill_this_buffer_proxy
4382 
4383    DESCRIPTION
4384    IL client uses this method to release the frame buffer
4385    after displaying them.
4386 
4387    PARAMETERS
4388    None.
4389 
4390    RETURN VALUE
4391    true/false
4392 
4393    ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)4394 OMX_ERRORTYPE  omx_video::fill_this_buffer_proxy(
4395         OMX_IN OMX_HANDLETYPE        hComp,
4396         OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
4397 {
4398     VIDC_TRACE_NAME_HIGH("FTB");
4399     (void)hComp;
4400     OMX_U8 *pmem_data_buf = NULL;
4401     OMX_ERRORTYPE nRet = OMX_ErrorNone;
4402     auto_lock l(m_buf_lock);
4403     if (m_buffer_freed == true) {
4404         DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid call. Called after freebuffer");
4405         return OMX_ErrorBadParameter;
4406     }
4407 
4408     if (bufferAdd != NULL) {
4409         DEBUG_PRINT_LOW("FTBProxy: bufferAdd->pBuffer[%p]", bufferAdd->pBuffer);
4410     }
4411     if (bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= (int)m_sOutPortDef.nBufferCountActual) ) {
4412         DEBUG_PRINT_ERROR("ERROR: FTBProxy: Invalid i/p params");
4413         return OMX_ErrorBadParameter;
4414     }
4415 
4416     pending_output_buffers++;
4417     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4418     /*Return back the output buffer to client*/
4419     if ( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true) {
4420         DEBUG_PRINT_LOW("o/p port is Disabled or Flush in Progress");
4421         post_event ((unsigned long)bufferAdd,0,
4422                 OMX_COMPONENT_GENERATE_FBD);
4423         return OMX_ErrorNone;
4424     }
4425 
4426     if (output_use_buffer && !m_use_output_pmem) {
4427         DEBUG_PRINT_LOW("Heap UseBuffer case");
4428         pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
4429     }
4430 
4431     if (dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true) {
4432         DEBUG_PRINT_ERROR("ERROR: dev_fill_buf() Failed");
4433         post_event ((unsigned long)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
4434         pending_output_buffers--;
4435         VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4436         return OMX_ErrorBadParameter;
4437     }
4438 
4439     return OMX_ErrorNone;
4440 }
4441 
4442 /* ======================================================================
4443    FUNCTION
4444    omx_video::SetCallbacks
4445 
4446    DESCRIPTION
4447    Set the callbacks.
4448 
4449    PARAMETERS
4450    None.
4451 
4452    RETURN VALUE
4453    OMX Error None if everything successful.
4454 
4455    ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)4456 OMX_ERRORTYPE  omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
4457         OMX_IN OMX_CALLBACKTYPE* callbacks,
4458         OMX_IN OMX_PTR             appData)
4459 {
4460     (void)hComp;
4461 
4462     if (!callbacks)
4463        return OMX_ErrorBadParameter;
4464 
4465     m_pCallbacks       = *callbacks;
4466     DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
4467             m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
4468     m_app_data =    appData;
4469     return OMX_ErrorNone;
4470 }
4471 
4472 
4473 /* ======================================================================
4474    FUNCTION
4475    omx_venc::UseEGLImage
4476 
4477    DESCRIPTION
4478    OMX Use EGL Image method implementation <TBD>.
4479 
4480    PARAMETERS
4481    <TBD>.
4482 
4483    RETURN VALUE
4484    Not Implemented error.
4485 
4486    ========================================================================== */
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)4487 OMX_ERRORTYPE  omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE   hComp,
4488         OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4489         OMX_IN OMX_U32                        port,
4490         OMX_IN OMX_PTR                     appData,
4491         OMX_IN void*                      eglImage)
4492 {
4493     (void)hComp, (void)bufferHdr, (void)port, (void)appData, (void)eglImage;
4494     DEBUG_PRINT_ERROR("ERROR: use_EGL_image:  Not Implemented");
4495     return OMX_ErrorNotImplemented;
4496 }
4497 
4498 /* ======================================================================
4499    FUNCTION
4500    omx_venc::ComponentRoleEnum
4501 
4502    DESCRIPTION
4503    OMX Component Role Enum method implementation.
4504 
4505    PARAMETERS
4506    <TBD>.
4507 
4508    RETURN VALUE
4509    OMX Error None if everything is successful.
4510    ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)4511 OMX_ERRORTYPE  omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
4512         OMX_OUT OMX_U8*        role,
4513         OMX_IN OMX_U32        index)
4514 {
4515     (void)hComp;
4516     OMX_ERRORTYPE eRet = OMX_ErrorNone;
4517     if (!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
4518         if ((0 == index) && role) {
4519             strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
4520             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4521         } else {
4522             DEBUG_PRINT_ERROR("ERROR: No more roles");
4523             eRet = OMX_ErrorNoMore;
4524         }
4525     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
4526         if ((0 == index) && role) {
4527             strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
4528             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4529         } else {
4530             DEBUG_PRINT_ERROR("ERROR: No more roles");
4531             eRet = OMX_ErrorNoMore;
4532         }
4533     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.vp8",OMX_MAX_STRINGNAME_SIZE)) {
4534         if ((0 == index) && role) {
4535             strlcpy((char *)role, "video_encoder.vp8",OMX_MAX_STRINGNAME_SIZE);
4536             DEBUG_PRINT_LOW("component_role_enum: role %s",role);
4537         } else {
4538             DEBUG_PRINT_ERROR("ERROR: No more roles");
4539             eRet = OMX_ErrorNoMore;
4540         }
4541     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc", OMX_MAX_STRINGNAME_SIZE) ||
4542               !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.hevc.cq", OMX_MAX_STRINGNAME_SIZE) ||
4543               !strncmp((char*)m_nkind, "OMX.qcom.video.encoder.heic", OMX_MAX_STRINGNAME_SIZE)) {
4544         if ((0 == index) && role) {
4545             strlcpy((char *)role, "video_encoder.hevc", OMX_MAX_STRINGNAME_SIZE);
4546             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
4547         } else {
4548             DEBUG_PRINT_ERROR("ERROR: No more roles");
4549             eRet = OMX_ErrorNoMore;
4550         }
4551     } else if (!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.tme", OMX_MAX_STRINGNAME_SIZE)) {
4552         if ((0 == index) && role) {
4553             strlcpy((char *)role, "video_encoder.tme", OMX_MAX_STRINGNAME_SIZE);
4554             DEBUG_PRINT_LOW("component_role_enum: role %s", role);
4555         } else {
4556             DEBUG_PRINT_ERROR("ERROR: No more roles");
4557             eRet = OMX_ErrorNoMore;
4558         }
4559     }
4560     else {
4561         DEBUG_PRINT_ERROR("ERROR: Querying Role on Unknown Component");
4562         eRet = OMX_ErrorInvalidComponentName;
4563     }
4564     return eRet;
4565 }
4566 
4567 
4568 
4569 
4570 /* ======================================================================
4571    FUNCTION
4572    omx_venc::AllocateDone
4573 
4574    DESCRIPTION
4575    Checks if entire buffer pool is allocated by IL Client or not.
4576    Need this to move to IDLE state.
4577 
4578    PARAMETERS
4579    None.
4580 
4581    RETURN VALUE
4582    true/false.
4583 
4584    ========================================================================== */
allocate_done(void)4585 bool omx_video::allocate_done(void)
4586 {
4587     bool bRet = false;
4588     bool bRet_In = false;
4589     bool bRet_Out = false;
4590     bool bRet_Out_Extra = false;
4591     bool bRet_In_Extra = false;
4592 
4593     bRet_In = allocate_input_done();
4594     bRet_Out = allocate_output_done();
4595     bRet_In_Extra =  allocate_input_extradata_done();
4596     bRet_Out_Extra = allocate_output_extradata_done();
4597 
4598     if (bRet_In && bRet_Out && bRet_Out_Extra && bRet_In_Extra) {
4599         bRet = true;
4600     }
4601 
4602     return bRet;
4603 }
4604 /* ======================================================================
4605    FUNCTION
4606    omx_venc::AllocateInputDone
4607 
4608    DESCRIPTION
4609    Checks if I/P buffer pool is allocated by IL Client or not.
4610 
4611    PARAMETERS
4612    None.
4613 
4614    RETURN VALUE
4615    true/false.
4616 
4617    ========================================================================== */
allocate_input_done(void)4618 bool omx_video::allocate_input_done(void)
4619 {
4620     bool bRet = false;
4621     unsigned i=0;
4622 
4623     if (m_inp_mem_ptr == NULL) {
4624         return bRet;
4625     }
4626     if (m_inp_mem_ptr ) {
4627         for (; i<m_sInPortDef.nBufferCountActual; i++) {
4628             if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4629                 break;
4630             }
4631         }
4632     }
4633     if (i==m_sInPortDef.nBufferCountActual) {
4634         bRet = true;
4635     }
4636     if (i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled) {
4637         m_sInPortDef.bPopulated = OMX_TRUE;
4638     }
4639     return bRet;
4640 }
4641 /* ======================================================================
4642    FUNCTION
4643    omx_venc::AllocateOutputDone
4644 
4645    DESCRIPTION
4646    Checks if entire O/P buffer pool is allocated by IL Client or not.
4647 
4648    PARAMETERS
4649    None.
4650 
4651    RETURN VALUE
4652    true/false.
4653 
4654    ========================================================================== */
allocate_output_done(void)4655 bool omx_video::allocate_output_done(void)
4656 {
4657     bool bRet = false;
4658     unsigned j=0;
4659 
4660     if (m_out_mem_ptr == NULL) {
4661         return bRet;
4662     }
4663 
4664     if (m_out_mem_ptr ) {
4665         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4666             if (BITMASK_ABSENT(&m_out_bm_count,j)) {
4667                 break;
4668             }
4669         }
4670     }
4671 
4672     if (j==m_sOutPortDef.nBufferCountActual) {
4673         bRet = true;
4674     }
4675 
4676     if (j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled) {
4677         m_sOutPortDef.bPopulated = OMX_TRUE;
4678     }
4679     return bRet;
4680 }
4681 
allocate_output_extradata_done(void)4682 bool omx_video::allocate_output_extradata_done(void) {
4683     bool bRet = false;
4684     unsigned j=0;
4685     unsigned nBufferCount = 0;
4686 
4687     nBufferCount = m_client_out_extradata_info.getBufferCount();
4688 
4689     if (!m_client_out_extradata_info.is_client_extradata_enabled()) {
4690         return true;
4691     }
4692 
4693     if (m_client_output_extradata_mem_ptr) {
4694         for (; j < nBufferCount; j++) {
4695             if (BITMASK_ABSENT(&m_out_extradata_bm_count,j)) {
4696                 break;
4697             }
4698         }
4699 
4700         if (j == nBufferCount) {
4701             bRet = true;
4702             DEBUG_PRINT_HIGH("Allocate done for all extradata o/p buffers");
4703         }
4704     }
4705 
4706     return bRet;
4707 }
4708 
allocate_input_extradata_done(void)4709 bool omx_video::allocate_input_extradata_done(void) {
4710     bool bRet = false;
4711     unsigned j=0;
4712     unsigned nBufferCount = 0;
4713 
4714     nBufferCount = m_client_in_extradata_info.getBufferCount();
4715 
4716     if (!m_client_in_extradata_info.is_client_extradata_enabled()) {
4717         return true;
4718     }
4719 
4720     if (m_client_input_extradata_mem_ptr) {
4721         for (; j < nBufferCount; j++) {
4722             if (BITMASK_ABSENT(&m_in_extradata_bm_count,j)) {
4723                 break;
4724             }
4725         }
4726 
4727         if (j == nBufferCount) {
4728             bRet = true;
4729             DEBUG_PRINT_HIGH("Allocate done for all extradata i/p buffers");
4730         }
4731     }
4732 
4733     return bRet;
4734 }
4735 
4736 /* ======================================================================
4737    FUNCTION
4738    omx_venc::ReleaseDone
4739 
4740    DESCRIPTION
4741    Checks if IL client has released all the buffers.
4742 
4743    PARAMETERS
4744    None.
4745 
4746    RETURN VALUE
4747    true/false
4748 
4749    ========================================================================== */
release_done(void)4750 bool omx_video::release_done(void)
4751 {
4752     bool bRet = false;
4753     DEBUG_PRINT_LOW("Inside release_done()");
4754     if (release_input_done()) {
4755         if (release_output_done()) {
4756             if (release_output_extradata_done()) {
4757                 bRet = true;
4758             }
4759         }
4760     }
4761     return bRet;
4762 }
4763 
4764 
4765 /* ======================================================================
4766    FUNCTION
4767    omx_venc::ReleaseOutputDone
4768 
4769    DESCRIPTION
4770    Checks if IL client has released all the buffers.
4771 
4772    PARAMETERS
4773    None.
4774 
4775    RETURN VALUE
4776    true/false
4777 
4778    ========================================================================== */
release_output_done(void)4779 bool omx_video::release_output_done(void)
4780 {
4781     bool bRet = false;
4782     unsigned i=0,j=0;
4783 
4784     DEBUG_PRINT_LOW("Inside release_output_done()");
4785     if (m_out_mem_ptr) {
4786         for (; j<m_sOutPortDef.nBufferCountActual; j++) {
4787             if (BITMASK_PRESENT(&m_out_bm_count,j)) {
4788                 break;
4789             }
4790         }
4791         if (j==m_sOutPortDef.nBufferCountActual) {
4792             bRet = true;
4793         }
4794     } else {
4795         bRet = true;
4796     }
4797     return bRet;
4798 }
4799 /* ======================================================================
4800    FUNCTION
4801    omx_venc::ReleaseInputDone
4802 
4803    DESCRIPTION
4804    Checks if IL client has released all the buffers.
4805 
4806    PARAMETERS
4807    None.
4808 
4809    RETURN VALUE
4810    true/false
4811 
4812    ========================================================================== */
release_input_done(void)4813 bool omx_video::release_input_done(void)
4814 {
4815     bool bRet = false;
4816     unsigned i=0,j=0;
4817 
4818     DEBUG_PRINT_LOW("Inside release_input_done()");
4819     if (m_inp_mem_ptr) {
4820         for (; j<m_sInPortDef.nBufferCountActual; j++) {
4821             if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
4822                 break;
4823             }
4824         }
4825         if (j==m_sInPortDef.nBufferCountActual) {
4826             bRet = true;
4827         }
4828     } else {
4829         bRet = true;
4830     }
4831     return bRet;
4832 }
4833 
release_output_extradata_done(void)4834 bool omx_video::release_output_extradata_done(void) {
4835     bool bRet = false;
4836     unsigned i=0,j=0, buffer_count=0;
4837 
4838     buffer_count = m_client_out_extradata_info.getBufferCount();
4839     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4840             m_client_output_extradata_mem_ptr, buffer_count);
4841 
4842     if (m_client_output_extradata_mem_ptr) {
4843         for (; j<buffer_count; j++) {
4844             if ( BITMASK_PRESENT(&m_out_extradata_bm_count,j)) {
4845                 break;
4846             }
4847         }
4848         if (j == buffer_count) {
4849             bRet = true;
4850         }
4851     } else {
4852         bRet = true;
4853     }
4854     return bRet;
4855 }
4856 
release_input_extradata_done(void)4857 bool omx_video::release_input_extradata_done(void) {
4858     bool bRet = false;
4859     unsigned i=0,j=0, buffer_count=0;
4860 
4861     buffer_count = m_client_in_extradata_info.getBufferCount();
4862     DEBUG_PRINT_LOW("Value of m_client_output_extradata_mem_ptr %p buffer_count - %d",
4863             m_client_input_extradata_mem_ptr, buffer_count);
4864 
4865     if (m_client_input_extradata_mem_ptr) {
4866         for (; j<buffer_count; j++) {
4867             if ( BITMASK_PRESENT(&m_in_extradata_bm_count,j)) {
4868                 break;
4869             }
4870         }
4871         if (j == buffer_count) {
4872             bRet = true;
4873         }
4874     } else {
4875         bRet = true;
4876     }
4877     return bRet;
4878 }
4879 
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4880 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
4881         OMX_BUFFERHEADERTYPE * buffer)
4882 {
4883     VIDC_TRACE_NAME_HIGH("FBD");
4884     int index = buffer - m_out_mem_ptr;
4885 
4886     DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %u",
4887             buffer->pBuffer, (unsigned)buffer->nFlags, (unsigned int)buffer->nFilledLen);
4888     if (buffer == NULL || ((buffer - m_out_mem_ptr) > (int)m_sOutPortDef.nBufferCountActual)) {
4889         return OMX_ErrorBadParameter;
4890     }
4891 
4892     pending_output_buffers--;
4893     VIDC_TRACE_INT_LOW("FTB-pending", pending_output_buffers);
4894     VIDC_TRACE_INT_LOW("FBD-TS", buffer->nTimeStamp / 1000);
4895     VIDC_TRACE_INT_LOW("FBD-size", buffer->nFilledLen);
4896 
4897     if (secure_session && m_pCallbacks.FillBufferDone) {
4898         if (buffer->nFilledLen > 0)
4899             m_fbd_count++;
4900         m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4901         return OMX_ErrorNone;
4902     }
4903 
4904     /* For use buffer we need to copy the data */
4905     if (m_pCallbacks.FillBufferDone) {
4906         if (buffer->nFilledLen > 0) {
4907             m_fbd_count++;
4908 
4909             if (dev_get_output_log_flag()) {
4910                 do_cache_operations(m_pOutput_ion[index].data_fd);
4911                 dev_output_log_buffers((const char*)buffer->pBuffer + buffer->nOffset, buffer->nFilledLen,
4912                                         buffer->nTimeStamp);
4913                 do_cache_operations(m_pOutput_ion[index].data_fd);
4914 
4915             }
4916         }
4917         if (buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
4918             if (!dev_handle_output_extradata((void *)buffer, index))
4919                 DEBUG_PRINT_ERROR("Failed to parse output extradata");
4920 
4921             dev_extradata_log_buffers((char *)(((unsigned long)buffer->pBuffer + buffer->nOffset +
4922                         buffer->nFilledLen + 3) & (~3)), false);
4923         }
4924         m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4925     } else {
4926         return OMX_ErrorBadParameter;
4927     }
4928     return OMX_ErrorNone;
4929 }
4930 
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4931 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE         hComp,
4932         OMX_BUFFERHEADERTYPE* buffer)
4933 {
4934     VIDC_TRACE_NAME_HIGH("EBD");
4935     int buffer_index  = -1;
4936 
4937     buffer_index = buffer - ((mUseProxyColorFormat && !mUsesColorConversion) ? meta_buffer_hdr : m_inp_mem_ptr);
4938     DEBUG_PRINT_LOW("empty_buffer_done: buffer[%p]", buffer);
4939     if (buffer == NULL ||
4940             ((buffer_index > (int)m_sInPortDef.nBufferCountActual))) {
4941         DEBUG_PRINT_ERROR("ERROR in empty_buffer_done due to index buffer");
4942         return OMX_ErrorBadParameter;
4943     }
4944 
4945     pending_input_buffers--;
4946     VIDC_TRACE_INT_LOW("ETB-pending", pending_input_buffers);
4947 
4948     if (mUseProxyColorFormat &&
4949         (buffer_index >= 0 && (buffer_index < (int)m_sInPortDef.nBufferCountActual))) {
4950         if (!pdest_frame  && !input_flush_progress && mUsesColorConversion) {
4951             pdest_frame = buffer;
4952             DEBUG_PRINT_LOW("empty_buffer_done pdest_frame address is %p",pdest_frame);
4953             return push_input_buffer(hComp);
4954         }
4955         if (mUsesColorConversion) {
4956             // return color-conversion buffer back to the pool
4957             DEBUG_PRINT_LOW("empty_buffer_done insert address is %p",buffer);
4958             if (!m_opq_pmem_q.insert_entry((unsigned long)buffer, 0, 0)) {
4959                 DEBUG_PRINT_ERROR("empty_buffer_done: pmem queue is full");
4960                 return OMX_ErrorBadParameter;
4961             }
4962         } else {
4963             // We are not dealing with color-conversion, Buffer being returned
4964             // here is client's buffer, return it back to client
4965             if (m_pCallbacks.EmptyBufferDone && buffer) {
4966                 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4967                 DEBUG_PRINT_LOW("empty_buffer_done: Returning client buf %p", buffer);
4968             }
4969         }
4970     } else if (m_pCallbacks.EmptyBufferDone) {
4971         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4972     }
4973     return OMX_ErrorNone;
4974 }
4975 
complete_pending_buffer_done_cbs()4976 void omx_video::complete_pending_buffer_done_cbs()
4977 {
4978     unsigned long p1;
4979     unsigned long p2;
4980     unsigned long ident;
4981     omx_cmd_queue tmp_q, pending_bd_q;
4982     pthread_mutex_lock(&m_lock);
4983     // pop all pending GENERATE FDB from ftb queue
4984     while (m_ftb_q.m_size) {
4985         m_ftb_q.pop_entry(&p1,&p2,&ident);
4986         if (ident == OMX_COMPONENT_GENERATE_FBD) {
4987             pending_bd_q.insert_entry(p1,p2,ident);
4988         } else {
4989             tmp_q.insert_entry(p1,p2,ident);
4990         }
4991     }
4992     //return all non GENERATE FDB to ftb queue
4993     while (tmp_q.m_size) {
4994         tmp_q.pop_entry(&p1,&p2,&ident);
4995         m_ftb_q.insert_entry(p1,p2,ident);
4996     }
4997     // pop all pending GENERATE EDB from etb queue
4998     while (m_etb_q.m_size) {
4999         m_etb_q.pop_entry(&p1,&p2,&ident);
5000         if (ident == OMX_COMPONENT_GENERATE_EBD) {
5001             pending_bd_q.insert_entry(p1,p2,ident);
5002         } else {
5003             tmp_q.insert_entry(p1,p2,ident);
5004         }
5005     }
5006     //return all non GENERATE FDB to etb queue
5007     while (tmp_q.m_size) {
5008         tmp_q.pop_entry(&p1,&p2,&ident);
5009         m_etb_q.insert_entry(p1,p2,ident);
5010     }
5011     pthread_mutex_unlock(&m_lock);
5012     // process all pending buffer dones
5013     while (pending_bd_q.m_size) {
5014         pending_bd_q.pop_entry(&p1,&p2,&ident);
5015         switch (ident) {
5016             case OMX_COMPONENT_GENERATE_EBD:
5017                 if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
5018                     DEBUG_PRINT_ERROR("ERROR: empty_buffer_done() failed!");
5019                     omx_report_error ();
5020                 }
5021                 break;
5022 
5023             case OMX_COMPONENT_GENERATE_FBD:
5024                 if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
5025                     DEBUG_PRINT_ERROR("ERROR: fill_buffer_done() failed!");
5026                     omx_report_error ();
5027                 }
5028                 break;
5029         }
5030     }
5031 }
5032 
do_cache_operations(int fd)5033 void omx_video::do_cache_operations(int fd)
5034 {
5035 #ifdef USE_ION
5036     struct dma_buf_sync buf_sync;
5037 
5038     if (fd < 0)
5039         return;
5040 
5041     struct dma_buf_sync dma_buf_sync_data[2];
5042     dma_buf_sync_data[0].flags = DMA_BUF_SYNC_START | DMA_BUF_SYNC_RW;
5043     dma_buf_sync_data[1].flags = DMA_BUF_SYNC_END | DMA_BUF_SYNC_RW;
5044 
5045     for(unsigned int i=0; i<2; i++) {
5046         int rc = ioctl(fd, DMA_BUF_IOCTL_SYNC, &dma_buf_sync_data[i]);
5047         if (rc < 0) {
5048             DEBUG_PRINT_ERROR("Failed DMA_BUF_IOCTL_SYNC %s fd : %d", i==0?"start":"end", fd);
5049             return;
5050         }
5051     }
5052 #else
5053     (void)fd;
5054     return;
5055 #endif
5056 }
5057 
ion_map(int fd,int len)5058 char *omx_video::ion_map(int fd, int len)
5059 {
5060     char *bufaddr = (char*)mmap(NULL, len, PROT_READ|PROT_WRITE,
5061                                 MAP_SHARED, fd, 0);
5062 #ifdef USE_ION
5063     if (bufaddr != MAP_FAILED) {
5064         do_cache_operations(fd);
5065     }
5066 #endif
5067     return bufaddr;
5068 }
5069 
ion_unmap(int fd,void * bufaddr,int len)5070 OMX_ERRORTYPE omx_video::ion_unmap(int fd, void *bufaddr, int len)
5071 {
5072 #ifdef USE_ION
5073     do_cache_operations(fd);
5074 #else
5075     (void)fd;
5076 #endif
5077     if (-1 == munmap(bufaddr, len)) {
5078         DEBUG_PRINT_ERROR("munmap failed.");
5079         return OMX_ErrorInsufficientResources;
5080     }
5081     return OMX_ErrorNone;
5082 }
5083 
5084 #ifdef USE_ION
alloc_map_ion_memory(int size,venc_ion * ion_info,int flag)5085 bool omx_video::alloc_map_ion_memory(int size, venc_ion *ion_info, int flag)
5086 {
5087     struct venc_ion buf_ion_info;
5088     int rc=0;
5089 
5090     if (size <=0 || !ion_info) {
5091         DEBUG_PRINT_ERROR("Invalid input to alloc_map_ion_memory");
5092         return false;
5093     }
5094 
5095     ion_info->data_fd = -1;
5096     ion_info->dev_fd = ion_open();
5097     if (ion_info->dev_fd <= 0) {
5098         DEBUG_PRINT_ERROR("ERROR: ION Device open() Failed");
5099         return false;
5100     }
5101 
5102     if(secure_session) {
5103         ion_info->alloc_data.len = (size + (SECURE_ALIGN - 1)) & ~(SECURE_ALIGN - 1);
5104         ion_info->alloc_data.flags = flag;
5105         ion_info->alloc_data.heap_id_mask = ION_HEAP(MEM_HEAP_ID);
5106         if (ion_info->alloc_data.flags & ION_FLAG_CP_BITSTREAM) {
5107             ion_info->alloc_data.heap_id_mask |= ION_HEAP(ION_SECURE_DISPLAY_HEAP_ID);
5108         }
5109         DEBUG_PRINT_HIGH("ION ALLOC sec buf: size %u flags %x",
5110                 (unsigned int)ion_info->alloc_data.len,
5111                 ion_info->alloc_data.flags);
5112     } else {
5113         ion_info->alloc_data.len = (size + (SZ_4K - 1)) & ~(SZ_4K - 1);
5114         ion_info->alloc_data.flags = (flag & ION_FLAG_CACHED);
5115 
5116         /* If color format is Vanilla NV12, we will need to use caching for optimal
5117            color alignment performance.
5118          */
5119 
5120         if (m_sInPortDef.format.video.eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
5121         {
5122             DEBUG_PRINT_HIGH("Enabling cacheing for this buffer");
5123             ion_info->alloc_data.flags = ION_FLAG_CACHED;
5124         }
5125         ion_info->alloc_data.heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
5126                                     ION_HEAP(ION_SYSTEM_HEAP_ID));
5127         DEBUG_PRINT_HIGH("ION ALLOC unsec buf: size %u flags %x",
5128                 (unsigned int)ion_info->alloc_data.len,
5129                 ion_info->alloc_data.flags);
5130     }
5131 #ifdef HYPERVISOR
5132     ion_info->alloc_data.flags &= (~ION_FLAG_CACHED);
5133 #endif
5134 
5135     rc = ion_alloc_fd(ion_info->dev_fd, ion_info->alloc_data.len, 0,
5136                       ion_info->alloc_data.heap_id_mask,
5137                       ion_info->alloc_data.flags, &ion_info->data_fd);
5138     if (rc || ion_info->data_fd < 0) {
5139         DEBUG_PRINT_ERROR("ION ALLOC memory failed 0x%x", rc);
5140         ion_close(ion_info->dev_fd);
5141         ion_info->data_fd = -1;
5142         ion_info->dev_fd = -1;
5143         return false;
5144     }
5145 
5146     return true;
5147 }
5148 
free_ion_memory(struct venc_ion * buf_ion_info)5149 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
5150 {
5151     if (!buf_ion_info) {
5152         DEBUG_PRINT_ERROR("Invalid input to free_ion_memory");
5153         return;
5154     }
5155     if (buf_ion_info->data_fd >= 0) {
5156         close(buf_ion_info->data_fd);
5157         buf_ion_info->data_fd = -1;
5158     }
5159     if (buf_ion_info->dev_fd >= 0) {
5160         ion_close(buf_ion_info->dev_fd);
5161         buf_ion_info->dev_fd = -1;
5162     }
5163 }
5164 #endif
5165 
5166 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)5167 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
5168 {
5169     if (buffer && meta_mode_enable) {
5170         LEGACY_CAM_METADATA_TYPE *media_ptr;
5171         struct pmem Input_pmem;
5172         unsigned int index_pmem = 0;
5173         bool meta_error = false;
5174 
5175         index_pmem = (buffer - m_inp_mem_ptr);
5176         if (mUsesColorConversion &&
5177                 (index_pmem < m_sInPortDef.nBufferCountActual)) {
5178             if (!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)) {
5179                 DEBUG_PRINT_ERROR("omx_release_meta_buffer dev free failed");
5180             }
5181         } else {
5182             media_ptr = (LEGACY_CAM_METADATA_TYPE *) buffer->pBuffer;
5183             if (media_ptr && media_ptr->meta_handle) {
5184                 if (media_ptr->buffer_type == LEGACY_CAM_SOURCE) {
5185                     Input_pmem.buffer = media_ptr;
5186                     Input_pmem.fd = MetaBufferUtil::getFdAt(media_ptr->meta_handle, 0);
5187                     int size = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5188                     int offset = MetaBufferUtil::getIntAt(media_ptr->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5189                     if (Input_pmem.fd < 0 || size < 0 || offset < 0) {
5190                         DEBUG_PRINT_ERROR("Invalid meta buffer");
5191                         meta_error = true;
5192                     }
5193                     Input_pmem.size = size;
5194                     Input_pmem.offset = offset;
5195                     DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
5196                             Input_pmem.offset,
5197                             Input_pmem.size);
5198                 } else if (media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
5199                     VideoGrallocMetadata *media_ptr = (VideoGrallocMetadata *)buffer->pBuffer;
5200                     private_handle_t *handle = (private_handle_t *)media_ptr->pHandle;
5201                     Input_pmem.buffer = media_ptr;
5202                     Input_pmem.fd = handle->fd;
5203                     Input_pmem.offset = 0;
5204                     Input_pmem.size = handle->size;
5205                 } else {
5206                     meta_error = true;
5207                 }
5208                 if (!meta_error)
5209                     meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
5210                 if (meta_error) {
5211                     DEBUG_PRINT_HIGH("In batchmode or dev_free_buf failed, flush %d",
5212                             input_flush_progress);
5213                 }
5214             }
5215         }
5216     }
5217 }
5218 #endif
5219 
is_ubwc_interlaced(private_handle_t * handle)5220 bool is_ubwc_interlaced(private_handle_t *handle) {
5221     int interlace_flag = 0;
5222 
5223     if (getMetaData(const_cast<private_handle_t *>(handle),
5224                   GET_PP_PARAM_INTERLACED, &interlace_flag)) {
5225         interlace_flag = 0;
5226     }
5227     return (handle->format == HAL_PIXEL_FORMAT_YCbCr_420_SP_VENUS_UBWC) &&
5228                 !!interlace_flag;
5229 }
5230 
is_conv_needed(private_handle_t * handle)5231 bool omx_video::is_conv_needed(private_handle_t *handle)
5232 {
5233     bool bRet = false;
5234     bool interlaced = is_ubwc_interlaced(handle);
5235 
5236     if (!strncmp(m_platform, "msm8996", 7)) {
5237         bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888 &&
5238             !(handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED ||
5239               handle->flags & private_handle_t::PRIV_FLAGS_UBWC_ALIGNED_PI);
5240     } else {
5241         bRet = handle->format == HAL_PIXEL_FORMAT_RGBA_8888;
5242     }
5243 
5244 #ifdef _HW_RGBA
5245     bRet = false;
5246 #endif
5247     bRet |= interlaced;
5248     DEBUG_PRINT_LOW("RGBA conversion %s. Format %d Flag %d interlace_flag = %d",
5249                                 bRet ? "Needed":"Not-Needed", handle->format,
5250                                 handle->flags, interlaced);
5251     return bRet;
5252 }
5253 
print_debug_color_aspects(ColorAspects * aspects,const char * prefix)5254 void omx_video::print_debug_color_aspects(ColorAspects *aspects, const char *prefix) {
5255     DEBUG_PRINT_HIGH("%s : Color aspects : Primaries = %d Range = %d Transfer = %d MatrixCoeffs = %d",
5256             prefix, aspects->mPrimaries, aspects->mRange, aspects->mTransfer, aspects->mMatrixCoeffs);
5257 }
5258 
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)5259 OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
5260         OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5261 {
5262     VIDC_TRACE_NAME_LOW("ETB-Opaque");
5263     unsigned nBufIndex = 0;
5264     OMX_ERRORTYPE ret = OMX_ErrorNone;
5265     VideoGrallocMetadata *media_buffer; // This method primarily assumes gralloc-metadata
5266     private_handle_t *handle = NULL;
5267     DEBUG_PRINT_LOW("ETBProxyOpaque: buffer[%p]", buffer);
5268 
5269     if (buffer == NULL) {
5270         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid buffer[%p]",buffer);
5271         return OMX_ErrorBadParameter;
5272     }
5273 
5274     if (profile_etb()) {
5275         m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5276         return OMX_ErrorNone;
5277     }
5278 
5279     if (!dev_buffer_ready_to_queue(buffer)) {
5280         DEBUG_PRINT_HIGH("Info: ETBProxyA: buffer[%p] is deffered", buffer);
5281         return OMX_ErrorNone;
5282     }
5283 
5284     nBufIndex = buffer - meta_buffer_hdr;
5285     if (nBufIndex >= m_sInPortDef.nBufferCountActual) {
5286         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Invalid bufindex = %u",
5287                 nBufIndex);
5288         return OMX_ErrorBadParameter;
5289     }
5290 
5291     media_buffer = (VideoGrallocMetadata *)buffer->pBuffer;
5292     if (!media_buffer) {
5293         DEBUG_PRINT_ERROR("%s: invalid media_buffer",__FUNCTION__);
5294         return OMX_ErrorBadParameter;
5295     }
5296     if ((media_buffer->eType == LEGACY_CAM_SOURCE)
5297             && buffer->nAllocLen != sizeof(LEGACY_CAM_METADATA_TYPE)) {
5298         DEBUG_PRINT_ERROR("Invalid metadata size expected(%u) v/s recieved(%zu)",
5299                 buffer->nAllocLen, sizeof(LEGACY_CAM_METADATA_TYPE));
5300         return OMX_ErrorBadParameter;
5301     }
5302 
5303     if (media_buffer && media_buffer->eType == LEGACY_CAM_SOURCE) {
5304         return empty_this_buffer_proxy(hComp, buffer);
5305     }
5306 
5307     if ((!media_buffer || !media_buffer->pHandle || media_buffer->eType != kMetadataBufferTypeGrallocSource) &&
5308             !(buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5309         DEBUG_PRINT_ERROR("Incorrect Buffer queued media buffer = %p",
5310             media_buffer);
5311         m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
5312         return OMX_ErrorBadParameter;
5313     } else if (media_buffer) {
5314         handle = (private_handle_t *)media_buffer->pHandle;
5315     }
5316 
5317     /*Enable following code once private handle color format is
5318       updated correctly*/
5319 
5320     if (buffer->nFilledLen > 0 && handle && !is_streamon_done((OMX_U32) PORT_INDEX_OUT)) {
5321 
5322         ColorConvertFormat c2dSrcFmt = RGBA8888;
5323         ColorConvertFormat c2dDestFmt = m_ubwc_supported ? NV12_UBWC : NV12_128m;
5324 
5325         ColorMapping::const_iterator found =
5326              mMapPixelFormat2Converter.find(handle->format);
5327 
5328         if (found != mMapPixelFormat2Converter.end() && is_conv_needed(handle)) {
5329             c2dSrcFmt = (ColorConvertFormat)found->second;
5330             c2dcc.setConversionNeeded(true);
5331         } else {
5332             DEBUG_PRINT_HIGH("Couldn't find color mapping for (%x).", handle->format);
5333             c2dcc.setConversionNeeded(false);
5334         }
5335 
5336         mUsesColorConversion = is_conv_needed(handle);
5337         bool interlaced = is_ubwc_interlaced(handle);
5338         int  full_range_flag = m_sConfigColorAspects.sAspects.mRange == ColorAspects::RangeFull ?
5339                                private_handle_t::PRIV_FLAGS_ITU_R_601_FR : 0;
5340 
5341         if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingImageHEIC)
5342             c2dDestFmt = NV12_512;
5343 
5344         if (c2dcc.getConversionNeeded() &&
5345             c2dcc.isPropChanged(m_sInPortDef.format.video.nFrameWidth,
5346                                 interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5347                                 m_sInPortDef.format.video.nFrameHeight,
5348                                 m_sInPortDef.format.video.nFrameWidth,
5349                                 m_sInPortDef.format.video.nFrameHeight,
5350                                 c2dSrcFmt, c2dDestFmt,
5351                                 handle->flags, handle->width)) {
5352             DEBUG_PRINT_HIGH("C2D setResolution (0x%X -> 0x%x) HxW (%dx%d) Stride (%d)",
5353                              c2dSrcFmt, c2dDestFmt,
5354                              m_sInPortDef.format.video.nFrameHeight,
5355                              m_sInPortDef.format.video.nFrameWidth,
5356                              handle->width);
5357             if (!c2dcc.setResolution(m_sInPortDef.format.video.nFrameWidth,
5358                                      interlaced ? ((m_sInPortDef.format.video.nFrameHeight + 1) / 2) :
5359                                      m_sInPortDef.format.video.nFrameHeight,
5360                                      m_sInPortDef.format.video.nFrameWidth,
5361                                      m_sInPortDef.format.video.nFrameHeight,
5362                                      c2dSrcFmt, c2dDestFmt,
5363                                      handle->flags | full_range_flag, handle->width)) {
5364                 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5365                 DEBUG_PRINT_ERROR("SetResolution failed");
5366                 return OMX_ErrorBadParameter;
5367             }
5368 
5369             mC2dSrcFmt = c2dSrcFmt;
5370             mC2DFrameHeight = m_sInPortDef.format.video.nFrameHeight;
5371             mC2DFrameWidth = m_sInPortDef.format.video.nFrameWidth;
5372 
5373             if (mC2dDestFmt != c2dDestFmt && !dev_set_format(c2dDestFmt)) {
5374                 DEBUG_PRINT_ERROR("cannot set color format");
5375                 return OMX_ErrorBadParameter;
5376             }
5377             mC2dDestFmt = c2dDestFmt;
5378         }
5379 
5380         dev_get_buf_req (&m_sInPortDef.nBufferCountMin,
5381                          &m_sInPortDef.nBufferCountActual,
5382                          &m_sInPortDef.nBufferSize,
5383                          m_sInPortDef.nPortIndex);
5384     }
5385 
5386     if (input_flush_progress == true) {
5387         m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5388         DEBUG_PRINT_ERROR("ERROR: ETBProxyA: Input flush in progress");
5389         return OMX_ErrorNone;
5390     }
5391 
5392     if (!psource_frame) {
5393         psource_frame = buffer;
5394         ret = push_input_buffer(hComp);
5395     } else {
5396         if (!m_opq_meta_q.insert_entry((unsigned long)buffer,0,0)) {
5397             DEBUG_PRINT_ERROR("ERROR: ETBProxy: Queue is full");
5398             m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
5399             ret = OMX_ErrorBadParameter;
5400         }
5401     }
5402     return ret;
5403 }
5404 
queue_meta_buffer(OMX_HANDLETYPE hComp)5405 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp)
5406 {
5407 
5408     OMX_ERRORTYPE ret = OMX_ErrorNone;
5409     unsigned long address = 0,p2,id;
5410 
5411     DEBUG_PRINT_LOW("In queue Meta Buffer");
5412     if (!psource_frame || !pdest_frame) {
5413         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5414         return OMX_ErrorBadParameter;
5415     }
5416 
5417     if (psource_frame->nFilledLen > 0) {
5418         if (dev_use_buf(PORT_INDEX_IN) != true) {
5419             DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5420             post_event ((unsigned long)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
5421             ret = OMX_ErrorBadParameter;
5422         }
5423     }
5424 
5425     if (ret == OMX_ErrorNone)
5426         ret = empty_this_buffer_proxy(hComp,psource_frame);
5427 
5428     if (ret == OMX_ErrorNone) {
5429         psource_frame = NULL;
5430         if (!psource_frame && m_opq_meta_q.m_size) {
5431             m_opq_meta_q.pop_entry(&address,&p2,&id);
5432             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5433         }
5434     } else {
5435         // there has been an error and source frame has been scheduled for an EBD
5436         psource_frame = NULL;
5437     }
5438     return ret;
5439 }
5440 
convert_queue_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info,unsigned long & index)5441 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
5442         struct pmem &Input_pmem_info,unsigned long &index)
5443 {
5444 
5445     unsigned char *uva;
5446     OMX_ERRORTYPE ret = OMX_ErrorNone;
5447     unsigned long address = 0,p2,id;
5448 
5449     DEBUG_PRINT_LOW("In Convert and queue Meta Buffer");
5450     if (!psource_frame || !pdest_frame) {
5451         DEBUG_PRINT_ERROR("convert_queue_buffer invalid params");
5452         return OMX_ErrorBadParameter;
5453     }
5454     if (secure_session) {
5455         DEBUG_PRINT_ERROR("cannot convert buffer during secure session");
5456         return OMX_ErrorInvalidState;
5457     }
5458 
5459     if (!psource_frame->nFilledLen) {
5460         if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
5461             pdest_frame->nFilledLen = psource_frame->nFilledLen;
5462             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5463             pdest_frame->nFlags = psource_frame->nFlags;
5464             DEBUG_PRINT_HIGH("Skipping color conversion for empty EOS Buffer "
5465                     "header=%p filled-len=%u", pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5466         } else {
5467             pdest_frame->nOffset = 0;
5468             pdest_frame->nFilledLen = 0;
5469             pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5470             pdest_frame->nFlags = psource_frame->nFlags;
5471             DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5472                     pdest_frame, (unsigned int)pdest_frame->nFilledLen);
5473         }
5474     } else if (c2dcc.getConversionNeeded()) {
5475         uva = (unsigned char *)ion_map(Input_pmem_info.fd,Input_pmem_info.size);
5476         if (uva == MAP_FAILED) {
5477             ret = OMX_ErrorBadParameter;
5478         } else {
5479             DEBUG_PRINT_HIGH("Start Color Conversion...");
5480             if (!c2dcc.convertC2D(Input_pmem_info.fd, uva,
5481                                   uva, m_pInput_pmem[index].fd,
5482                                   pdest_frame->pBuffer,
5483                                   pdest_frame->pBuffer)) {
5484                 DEBUG_PRINT_ERROR("Color Conversion failed");
5485                 ret = OMX_ErrorBadParameter;
5486             } else {
5487                 unsigned int buf_size = 0;
5488                 buf_size = c2dcc.getBuffSize(C2D_OUTPUT);
5489                 pdest_frame->nOffset = 0;
5490                 pdest_frame->nFilledLen = buf_size;
5491                 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
5492                 pdest_frame->nFlags = psource_frame->nFlags;
5493                 DEBUG_PRINT_LOW("Buffer header %p Filled len size %u",
5494                                 pdest_frame,
5495                                 (unsigned int)pdest_frame->nFilledLen);
5496             }
5497             ion_unmap(Input_pmem_info.fd, uva,Input_pmem_info.size);
5498         }
5499     }
5500     if (dev_use_buf(PORT_INDEX_IN) != true) {
5501         DEBUG_PRINT_ERROR("ERROR: in dev_use_buf");
5502         post_event ((unsigned long)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
5503         ret = OMX_ErrorBadParameter;
5504     }
5505     if (ret == OMX_ErrorNone)
5506         ret = empty_this_buffer_proxy(hComp,pdest_frame);
5507     if (ret == OMX_ErrorNone) {
5508         m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
5509         psource_frame = NULL;
5510         pdest_frame = NULL;
5511         if (!psource_frame && m_opq_meta_q.m_size) {
5512             m_opq_meta_q.pop_entry(&address,&p2,&id);
5513             psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5514         }
5515         if (!pdest_frame && m_opq_pmem_q.m_size) {
5516             m_opq_pmem_q.pop_entry(&address,&p2,&id);
5517             pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5518             DEBUG_PRINT_LOW("pdest_frame pop address is %p",pdest_frame);
5519         }
5520     } else {
5521         // there has been an error and source frame has been scheduled for an EBD
5522         psource_frame = NULL;
5523     }
5524     return ret;
5525 }
5526 
push_input_buffer(OMX_HANDLETYPE hComp)5527 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
5528 {
5529     unsigned long address = 0,p2,id, index = 0;
5530     OMX_ERRORTYPE ret = OMX_ErrorNone;
5531 
5532     DEBUG_PRINT_LOW("In push input buffer");
5533     if (!psource_frame && m_opq_meta_q.m_size) {
5534         m_opq_meta_q.pop_entry(&address,&p2,&id);
5535         psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
5536     }
5537     if (!pdest_frame && m_opq_pmem_q.m_size) {
5538         m_opq_pmem_q.pop_entry(&address,&p2,&id);
5539         pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
5540     }
5541     while (psource_frame != NULL && pdest_frame != NULL &&
5542             ret == OMX_ErrorNone) {
5543         struct pmem Input_pmem_info;
5544         LEGACY_CAM_METADATA_TYPE *media_buffer;
5545         index = pdest_frame - m_inp_mem_ptr;
5546         if (index >= m_sInPortDef.nBufferCountActual) {
5547             DEBUG_PRINT_ERROR("Output buffer index is wrong %u act count %u",
5548                     (unsigned int)index, (unsigned int)m_sInPortDef.nBufferCountActual);
5549             return OMX_ErrorBadParameter;
5550         }
5551 
5552         if (psource_frame->nFilledLen == 0 && (psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
5553             return handle_empty_eos_buffer();
5554         }
5555         media_buffer = (LEGACY_CAM_METADATA_TYPE *)psource_frame->pBuffer;
5556         /*Will enable to verify camcorder in current TIPS can be removed*/
5557         if (media_buffer->buffer_type == LEGACY_CAM_SOURCE) {
5558             Input_pmem_info.buffer = media_buffer;
5559             Input_pmem_info.fd = MetaBufferUtil::getFdAt(media_buffer->meta_handle, 0);
5560             Input_pmem_info.offset = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_OFFSET);
5561             Input_pmem_info.size = MetaBufferUtil::getIntAt(media_buffer->meta_handle, 0, MetaBufferUtil::INT_SIZE);
5562             m_graphicbuffer_size = Input_pmem_info.size;
5563             DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
5564                     Input_pmem_info.offset,
5565                     Input_pmem_info.size);
5566             ret = queue_meta_buffer(hComp);
5567         } else {
5568             VideoGrallocMetadata *media_buffer = (VideoGrallocMetadata *)psource_frame->pBuffer;
5569             private_handle_t *handle = (private_handle_t *)media_buffer->pHandle;
5570             bool is_venus_supported_format = (handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE ||
5571                 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32m ||
5572                 handle->format == QOMX_COLOR_FORMATYUV420PackedSemiPlanar32mCompressed ||
5573                 handle->format == QOMX_COLOR_FORMATYUV420SemiPlanarP010Venus ||
5574                 handle->format == QOMX_COLOR_Format32bitRGBA8888Compressed ||
5575                 handle->format == HAL_PIXEL_FORMAT_YCbCr_420_TP10_UBWC ||
5576                 handle->format == HAL_PIXEL_FORMAT_NV21_ZSL ||
5577                 handle->format == QOMX_COLOR_FormatYVU420SemiPlanar ||
5578                 handle->format == HAL_PIXEL_FORMAT_NV12_HEIF);
5579 
5580             Input_pmem_info.buffer = media_buffer;
5581             Input_pmem_info.fd = handle->fd;
5582             Input_pmem_info.offset = 0;
5583             Input_pmem_info.size = handle->size;
5584             m_graphicbuffer_size = Input_pmem_info.size;
5585             if (is_conv_needed(handle))
5586                 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
5587             else if (is_venus_supported_format)
5588                 ret = queue_meta_buffer(hComp);
5589             else
5590                 ret = OMX_ErrorBadParameter;
5591         }
5592     }
5593     return ret;
5594 }
5595 
handle_empty_eos_buffer(void)5596 OMX_ERRORTYPE omx_video::handle_empty_eos_buffer(void)
5597 {
5598     if(!dev_handle_empty_eos_buffer())
5599         return OMX_ErrorHardware;
5600     else
5601         return OMX_ErrorNone;
5602 }
5603 
5604 // no code beyond this !
5605 
5606 // inline import of vendor extensions implementation
5607 #include "omx_video_extensions.hpp"
5608