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