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