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