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