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