omx_video_base.cpp revision c738fc6ffa6c0a3e3d2baf91fd52bea456cc37b6
1/*--------------------------------------------------------------------------
2Copyright (c) 2010-2012, 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(): m_state(OMX_StateInvalid),
227                        m_app_data(NULL),
228                        m_inp_mem_ptr(NULL),
229                        m_out_mem_ptr(NULL),
230                        m_pInput_pmem(NULL),
231                        m_pOutput_pmem(NULL),
232#ifdef USE_ION
233                        m_pInput_ion(NULL),
234                        m_pOutput_ion(NULL),
235#endif
236                        pending_input_buffers(0),
237                        pending_output_buffers(0),
238                        m_out_bm_count(0),
239                        m_inp_bm_count(0),
240                        m_flags(0),
241                        m_event_port_settings_sent(false),
242                        output_flush_progress (false),
243                        input_flush_progress (false),
244                        input_use_buffer (false),
245                        output_use_buffer (false),
246                        m_use_input_pmem(OMX_FALSE),
247                        m_use_output_pmem(OMX_FALSE),
248                        m_etb_count(0),
249                        m_fbd_count(0),
250                        m_error_propogated(false),
251                        m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
252                        psource_frame(NULL),
253                        pdest_frame(NULL),
254                        c2d_opened(false),
255                        secure_session(false)
256{
257  DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
258  memset(&m_cmp,0,sizeof(m_cmp));
259  memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
260  secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar;
261  pthread_mutex_init(&m_lock, NULL);
262  sem_init(&m_cmd_lock,0,0);
263}
264
265
266/* ======================================================================
267FUNCTION
268  omx_venc::~omx_venc
269
270DESCRIPTION
271  Destructor
272
273PARAMETERS
274  None
275
276RETURN VALUE
277  None.
278========================================================================== */
279omx_video::~omx_video()
280{
281  DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
282  if(m_pipe_in) close(m_pipe_in);
283  if(m_pipe_out) close(m_pipe_out);
284  DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
285  pthread_join(msg_thread_id,NULL);
286  DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
287  pthread_join(async_thread_id,NULL);
288  pthread_mutex_destroy(&m_lock);
289  sem_destroy(&m_cmd_lock);
290  DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
291      m_fbd_count);
292  DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
293  DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
294}
295
296/* ======================================================================
297FUNCTION
298  omx_venc::OMXCntrlProcessMsgCb
299
300DESCRIPTION
301  IL Client callbacks are generated through this routine. The decoder
302  provides the thread context for this routine.
303
304PARAMETERS
305  ctxt -- Context information related to the self.
306  id   -- Event identifier. This could be any of the following:
307          1. Command completion event
308          2. Buffer done callback event
309          3. Frame done callback event
310
311RETURN VALUE
312  None.
313
314========================================================================== */
315void omx_video::process_event_cb(void *ctxt, unsigned char id)
316{
317  unsigned p1; // Parameter - 1
318  unsigned p2; // Parameter - 2
319  unsigned ident;
320  unsigned qsize=0; // qsize
321  omx_video *pThis = (omx_video *) ctxt;
322
323  if(!pThis)
324  {
325    DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
326    return;
327  }
328
329  // Protect the shared queue data structure
330  do
331  {
332    /*Read the message id's from the queue*/
333
334    pthread_mutex_lock(&pThis->m_lock);
335    qsize = pThis->m_cmd_q.m_size;
336    if(qsize)
337    {
338      pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
339    }
340
341    if(qsize == 0)
342    {
343      qsize = pThis->m_ftb_q.m_size;
344      if(qsize)
345      {
346        pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
347      }
348    }
349
350    if(qsize == 0)
351    {
352      qsize = pThis->m_etb_q.m_size;
353      if(qsize)
354      {
355        pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
356      }
357    }
358
359    pthread_mutex_unlock(&pThis->m_lock);
360
361    /*process message if we have one*/
362    if(qsize > 0)
363    {
364      id = ident;
365      switch(id)
366      {
367      case OMX_COMPONENT_GENERATE_EVENT:
368        if(pThis->m_pCallbacks.EventHandler)
369        {
370          switch(p1)
371          {
372          case OMX_CommandStateSet:
373            pThis->m_state = (OMX_STATETYPE) p2;
374            DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
375            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
376                                             OMX_EventCmdComplete, p1, p2, NULL);
377            break;
378
379          case OMX_EventError:
380            DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
381            if(p2 == OMX_ErrorHardware)
382            {
383              pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
384                                               OMX_EventError,OMX_ErrorHardware,0,NULL);
385            }
386            else
387            {
388              pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
389                                               OMX_EventError, p2, NULL, NULL );
390
391            }
392            break;
393
394          case OMX_CommandPortDisable:
395            DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
396                        "state \n", p2);
397            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
398                                             OMX_EventCmdComplete, p1, p2, NULL );
399            break;
400          case OMX_CommandPortEnable:
401            DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
402                        , p2);
403            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
404                                             OMX_EventCmdComplete, p1, p2, NULL );
405            break;
406
407          default:
408            DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1);
409            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
410                                             OMX_EventCmdComplete, p1, p2, NULL );
411            break;
412
413          }
414        }
415        else
416        {
417          DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
418        }
419        break;
420      case OMX_COMPONENT_GENERATE_ETB_OPQ:
421        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n");
422        if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
423                                          (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
424        {
425          DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
426          pThis->omx_report_error ();
427        }
428        break;
429      case OMX_COMPONENT_GENERATE_ETB:
430        DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n");
431        if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
432                                          (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
433        {
434          DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
435          pThis->omx_report_error ();
436        }
437        break;
438
439      case OMX_COMPONENT_GENERATE_FTB:
440        if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
441                                          (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
442        {
443          DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
444          pThis->omx_report_error ();
445        }
446        break;
447
448      case OMX_COMPONENT_GENERATE_COMMAND:
449        pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
450                                  (OMX_U32)p2,(OMX_PTR)NULL);
451        break;
452
453      case OMX_COMPONENT_GENERATE_EBD:
454        if( pThis->empty_buffer_done(&pThis->m_cmp,
455                                     (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
456        {
457          DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
458          pThis->omx_report_error ();
459        }
460        break;
461
462      case OMX_COMPONENT_GENERATE_FBD:
463        if( pThis->fill_buffer_done(&pThis->m_cmp,
464                                    (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
465        {
466          DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
467          pThis->omx_report_error ();
468        }
469        break;
470
471      case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
472
473        pThis->input_flush_progress = false;
474        DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
475        m_etb_count = 0;
476        if(pThis->m_pCallbacks.EventHandler)
477        {
478          /*Check if we need generate event for Flush done*/
479          if(BITMASK_PRESENT(&pThis->m_flags,
480                             OMX_COMPONENT_INPUT_FLUSH_PENDING))
481          {
482            BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
483            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
484                                             OMX_EventCmdComplete,OMX_CommandFlush,
485                                             PORT_INDEX_IN,NULL );
486          }
487          else if(BITMASK_PRESENT(&pThis->m_flags,
488                                  OMX_COMPONENT_IDLE_PENDING))
489          {
490            if(!pThis->output_flush_progress)
491            {
492              DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n");
493              if(dev_stop() != 0)
494              {
495                DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
496                pThis->omx_report_error ();
497              }
498            }
499          }
500        }
501
502        break;
503
504      case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
505
506        pThis->output_flush_progress = false;
507        DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
508        m_fbd_count = 0;
509        if(pThis->m_pCallbacks.EventHandler)
510        {
511          /*Check if we need generate event for Flush done*/
512          if(BITMASK_PRESENT(&pThis->m_flags,
513                             OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
514          {
515            BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
516
517            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
518                                             OMX_EventCmdComplete,OMX_CommandFlush,
519                                             PORT_INDEX_OUT,NULL );
520          }
521          else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
522          {
523            DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n");
524            if(!pThis->input_flush_progress)
525            {
526              if(dev_stop() != 0)
527              {
528                DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
529                pThis->omx_report_error ();
530              }
531            }
532          }
533        }
534        break;
535
536      case OMX_COMPONENT_GENERATE_START_DONE:
537        DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
538
539        if(pThis->m_pCallbacks.EventHandler)
540        {
541          DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
542          if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
543          {
544            DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
545                             executing");
546            // Send the callback now
547            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
548            pThis->m_state = OMX_StateExecuting;
549            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
550                                             OMX_EventCmdComplete,OMX_CommandStateSet,
551                                             OMX_StateExecuting, NULL);
552          }
553          else if(BITMASK_PRESENT(&pThis->m_flags,
554                                  OMX_COMPONENT_PAUSE_PENDING))
555          {
556            if(dev_pause())
557            {
558              DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
559              pThis->omx_report_error ();
560            }
561          }
562          else if (BITMASK_PRESENT(&pThis->m_flags,
563                                   OMX_COMPONENT_LOADED_START_PENDING))
564          {
565            if(dev_loaded_start_done())
566            {
567              DEBUG_PRINT_LOW("successful loaded Start Done!");
568            }
569            else
570            {
571              DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
572              pThis->omx_report_error ();
573            }
574            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
575          }
576          else
577          {
578            DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
579          }
580        }
581        else
582        {
583          DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
584        }
585        break;
586
587      case OMX_COMPONENT_GENERATE_PAUSE_DONE:
588        DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
589        if(pThis->m_pCallbacks.EventHandler)
590        {
591          if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
592          {
593            //Send the callback now
594            pThis->complete_pending_buffer_done_cbs();
595            DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n");
596            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
597            pThis->m_state = OMX_StatePause;
598            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
599                                             OMX_EventCmdComplete,OMX_CommandStateSet,
600                                             OMX_StatePause, NULL);
601          }
602        }
603
604        break;
605
606      case OMX_COMPONENT_GENERATE_RESUME_DONE:
607        DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
608        if(pThis->m_pCallbacks.EventHandler)
609        {
610          if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
611          {
612            // Send the callback now
613            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
614            pThis->m_state = OMX_StateExecuting;
615            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
616                                             OMX_EventCmdComplete,OMX_CommandStateSet,
617                                             OMX_StateExecuting,NULL);
618          }
619        }
620
621        break;
622
623      case OMX_COMPONENT_GENERATE_STOP_DONE:
624        DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
625        if(pThis->m_pCallbacks.EventHandler)
626        {
627          pThis->complete_pending_buffer_done_cbs();
628          if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
629          {
630            // Send the callback now
631            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
632            pThis->m_state = OMX_StateIdle;
633            pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
634                                             OMX_EventCmdComplete,OMX_CommandStateSet,
635                                             OMX_StateIdle,NULL);
636          }
637          else if (BITMASK_PRESENT(&pThis->m_flags,
638                                   OMX_COMPONENT_LOADED_STOP_PENDING))
639          {
640            if(dev_loaded_stop_done())
641            {
642              DEBUG_PRINT_LOW("successful loaded Stop Done!");
643            }
644            else
645            {
646              DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
647              pThis->omx_report_error ();
648            }
649            BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
650          }
651          else
652          {
653            DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
654          }
655        }
656
657        break;
658
659      case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
660        DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
661        pThis->omx_report_error ();
662        break;
663
664      default:
665        DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id);
666        break;
667      }
668    }
669
670    pthread_mutex_lock(&pThis->m_lock);
671    qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
672            pThis->m_etb_q.m_size;
673
674    pthread_mutex_unlock(&pThis->m_lock);
675
676  }
677  while(qsize>0);
678  DEBUG_PRINT_LOW("\n exited the while loop\n");
679
680}
681
682
683
684
685/* ======================================================================
686FUNCTION
687  omx_venc::GetComponentVersion
688
689DESCRIPTION
690  Returns the component version.
691
692PARAMETERS
693  TBD.
694
695RETURN VALUE
696  OMX_ErrorNone.
697
698========================================================================== */
699OMX_ERRORTYPE  omx_video::get_component_version
700(
701OMX_IN OMX_HANDLETYPE hComp,
702OMX_OUT OMX_STRING componentName,
703OMX_OUT OMX_VERSIONTYPE* componentVersion,
704OMX_OUT OMX_VERSIONTYPE* specVersion,
705OMX_OUT OMX_UUIDTYPE* componentUUID
706)
707{
708  if(m_state == OMX_StateInvalid)
709  {
710    DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
711    return OMX_ErrorInvalidState;
712  }
713  /* TBD -- Return the proper version */
714  if (specVersion)
715  {
716    specVersion->nVersion = OMX_SPEC_VERSION;
717  }
718  return OMX_ErrorNone;
719}
720/* ======================================================================
721FUNCTION
722  omx_venc::SendCommand
723
724DESCRIPTION
725  Returns zero if all the buffers released..
726
727PARAMETERS
728  None.
729
730RETURN VALUE
731  true/false
732
733========================================================================== */
734OMX_ERRORTYPE  omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
735                                       OMX_IN OMX_COMMANDTYPE cmd,
736                                       OMX_IN OMX_U32 param1,
737                                       OMX_IN OMX_PTR cmdData
738                                      )
739{
740  if(m_state == OMX_StateInvalid)
741  {
742    DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
743    return OMX_ErrorInvalidState;
744  }
745
746  if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
747  {
748    if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
749    {
750      DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
751      return OMX_ErrorBadPortIndex;
752    }
753  }
754  if(cmd == OMX_CommandMarkBuffer)
755  {
756    if(param1 != PORT_INDEX_IN)
757    {
758      DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
759      return OMX_ErrorBadPortIndex;
760    }
761    if(!cmdData)
762    {
763      DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
764      return OMX_ErrorBadParameter;
765    }
766  }
767
768  post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
769  sem_wait(&m_cmd_lock);
770  return OMX_ErrorNone;
771}
772
773/* ======================================================================
774FUNCTION
775  omx_venc::SendCommand
776
777DESCRIPTION
778  Returns zero if all the buffers released..
779
780PARAMETERS
781  None.
782
783RETURN VALUE
784  true/false
785
786========================================================================== */
787OMX_ERRORTYPE  omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
788                                             OMX_IN OMX_COMMANDTYPE cmd,
789                                             OMX_IN OMX_U32 param1,
790                                             OMX_IN OMX_PTR cmdData
791                                            )
792{
793  OMX_ERRORTYPE eRet = OMX_ErrorNone;
794  OMX_STATETYPE eState = (OMX_STATETYPE) param1;
795  int bFlag = 1;
796
797  if(cmd == OMX_CommandStateSet)
798  {
799    /***************************/
800    /* Current State is Loaded */
801    /***************************/
802    if(m_state == OMX_StateLoaded)
803    {
804      if(eState == OMX_StateIdle)
805      {
806        //if all buffers are allocated or all ports disabled
807        if(allocate_done() ||
808           ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
809        {
810          DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
811        }
812        else
813        {
814          DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
815          BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
816          // Skip the event notification
817          bFlag = 0;
818        }
819      }
820      /* Requesting transition from Loaded to Loaded */
821      else if(eState == OMX_StateLoaded)
822      {
823        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n");
824        post_event(OMX_EventError,OMX_ErrorSameState,\
825                   OMX_COMPONENT_GENERATE_EVENT);
826        eRet = OMX_ErrorSameState;
827      }
828      /* Requesting transition from Loaded to WaitForResources */
829      else if(eState == OMX_StateWaitForResources)
830      {
831        /* Since error is None , we will post an event
832           at the end of this function definition */
833        DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
834      }
835      /* Requesting transition from Loaded to Executing */
836      else if(eState == OMX_StateExecuting)
837      {
838        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
839        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
840                   OMX_COMPONENT_GENERATE_EVENT);
841        eRet = OMX_ErrorIncorrectStateTransition;
842      }
843      /* Requesting transition from Loaded to Pause */
844      else if(eState == OMX_StatePause)
845      {
846        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
847        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
848                   OMX_COMPONENT_GENERATE_EVENT);
849        eRet = OMX_ErrorIncorrectStateTransition;
850      }
851      /* Requesting transition from Loaded to Invalid */
852      else if(eState == OMX_StateInvalid)
853      {
854        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
855        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
856        eRet = OMX_ErrorInvalidState;
857      }
858      else
859      {
860        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
861                          eState);
862        eRet = OMX_ErrorBadParameter;
863      }
864    }
865
866    /***************************/
867    /* Current State is IDLE */
868    /***************************/
869    else if(m_state == OMX_StateIdle)
870    {
871      if(eState == OMX_StateLoaded)
872      {
873        if(release_done())
874        {
875          /*
876             Since error is None , we will post an event at the end
877             of this function definition
878          */
879          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
880          if(dev_stop() != 0)
881          {
882            DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
883            eRet = OMX_ErrorHardware;
884          }
885        }
886        else
887        {
888          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
889          BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
890          // Skip the event notification
891          bFlag = 0;
892        }
893      }
894      /* Requesting transition from Idle to Executing */
895      else if(eState == OMX_StateExecuting)
896      {
897        if( dev_start() )
898        {
899          DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
900          omx_report_error ();
901          eRet = OMX_ErrorHardware;
902        }
903        else
904        {
905          BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
906          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
907          bFlag = 0;
908        }
909
910	dev_start_done();
911      }
912      /* Requesting transition from Idle to Idle */
913      else if(eState == OMX_StateIdle)
914      {
915        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
916        post_event(OMX_EventError,OMX_ErrorSameState,\
917                   OMX_COMPONENT_GENERATE_EVENT);
918        eRet = OMX_ErrorSameState;
919      }
920      /* Requesting transition from Idle to WaitForResources */
921      else if(eState == OMX_StateWaitForResources)
922      {
923        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
924        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
925                   OMX_COMPONENT_GENERATE_EVENT);
926        eRet = OMX_ErrorIncorrectStateTransition;
927      }
928      /* Requesting transition from Idle to Pause */
929      else if(eState == OMX_StatePause)
930      {
931        /*To pause the Video core we need to start the driver*/
932        if( dev_start() )
933        {
934          DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
935          omx_report_error ();
936          eRet = OMX_ErrorHardware;
937        }
938        else
939        {
940          BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
941          DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
942          bFlag = 0;
943        }
944      }
945      /* Requesting transition from Idle to Invalid */
946      else if(eState == OMX_StateInvalid)
947      {
948        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
949        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
950        eRet = OMX_ErrorInvalidState;
951      }
952      else
953      {
954        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
955        eRet = OMX_ErrorBadParameter;
956      }
957    }
958
959    /******************************/
960    /* Current State is Executing */
961    /******************************/
962    else if(m_state == OMX_StateExecuting)
963    {
964      /* Requesting transition from Executing to Idle */
965      if(eState == OMX_StateIdle)
966      {
967        /* Since error is None , we will post an event
968        at the end of this function definition
969        */
970        DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
971        //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
972        BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
973        execute_omx_flush(OMX_ALL);
974        bFlag = 0;
975	dev_stop_done();
976      }
977      /* Requesting transition from Executing to Paused */
978      else if(eState == OMX_StatePause)
979      {
980
981        if(dev_pause())
982        {
983          DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
984          post_event(OMX_EventError,OMX_ErrorHardware,\
985                     OMX_COMPONENT_GENERATE_EVENT);
986          eRet = OMX_ErrorHardware;
987        }
988        else
989        {
990          BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
991          DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n");
992          bFlag = 0;
993        }
994      }
995      /* Requesting transition from Executing to Loaded */
996      else if(eState == OMX_StateLoaded)
997      {
998        DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
999        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1000                   OMX_COMPONENT_GENERATE_EVENT);
1001        eRet = OMX_ErrorIncorrectStateTransition;
1002      }
1003      /* Requesting transition from Executing to WaitForResources */
1004      else if(eState == OMX_StateWaitForResources)
1005      {
1006        DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
1007        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1008                   OMX_COMPONENT_GENERATE_EVENT);
1009        eRet = OMX_ErrorIncorrectStateTransition;
1010      }
1011      /* Requesting transition from Executing to Executing */
1012      else if(eState == OMX_StateExecuting)
1013      {
1014        DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
1015        post_event(OMX_EventError,OMX_ErrorSameState,\
1016                   OMX_COMPONENT_GENERATE_EVENT);
1017        eRet = OMX_ErrorSameState;
1018      }
1019      /* Requesting transition from Executing to Invalid */
1020      else if(eState == OMX_StateInvalid)
1021      {
1022        DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
1023        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1024        eRet = OMX_ErrorInvalidState;
1025      }
1026      else
1027      {
1028        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
1029        eRet = OMX_ErrorBadParameter;
1030      }
1031    }
1032    /***************************/
1033    /* Current State is Pause  */
1034    /***************************/
1035    else if(m_state == OMX_StatePause)
1036    {
1037      /* Requesting transition from Pause to Executing */
1038      if(eState == OMX_StateExecuting)
1039      {
1040        DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1041        if( dev_resume() )
1042        {
1043          post_event(OMX_EventError,OMX_ErrorHardware,\
1044                     OMX_COMPONENT_GENERATE_EVENT);
1045          eRet = OMX_ErrorHardware;
1046        }
1047        else
1048        {
1049          BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1050          DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n");
1051          post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE);
1052          bFlag = 0;
1053        }
1054      }
1055      /* Requesting transition from Pause to Idle */
1056      else if(eState == OMX_StateIdle)
1057      {
1058        /* Since error is None , we will post an event
1059        at the end of this function definition */
1060        DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1061        BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1062        execute_omx_flush(OMX_ALL);
1063        bFlag = 0;
1064      }
1065      /* Requesting transition from Pause to loaded */
1066      else if(eState == OMX_StateLoaded)
1067      {
1068        DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
1069        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1070                   OMX_COMPONENT_GENERATE_EVENT);
1071        eRet = OMX_ErrorIncorrectStateTransition;
1072      }
1073      /* Requesting transition from Pause to WaitForResources */
1074      else if(eState == OMX_StateWaitForResources)
1075      {
1076        DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
1077        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1078                   OMX_COMPONENT_GENERATE_EVENT);
1079        eRet = OMX_ErrorIncorrectStateTransition;
1080      }
1081      /* Requesting transition from Pause to Pause */
1082      else if(eState == OMX_StatePause)
1083      {
1084        DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
1085        post_event(OMX_EventError,OMX_ErrorSameState,\
1086                   OMX_COMPONENT_GENERATE_EVENT);
1087        eRet = OMX_ErrorSameState;
1088      }
1089      /* Requesting transition from Pause to Invalid */
1090      else if(eState == OMX_StateInvalid)
1091      {
1092        DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
1093        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1094        eRet = OMX_ErrorInvalidState;
1095      }
1096      else
1097      {
1098        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
1099        eRet = OMX_ErrorBadParameter;
1100      }
1101    }
1102    /***************************/
1103    /* Current State is WaitForResources  */
1104    /***************************/
1105    else if(m_state == OMX_StateWaitForResources)
1106    {
1107      /* Requesting transition from WaitForResources to Loaded */
1108      if(eState == OMX_StateLoaded)
1109      {
1110        /* Since error is None , we will post an event
1111        at the end of this function definition */
1112        DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
1113      }
1114      /* Requesting transition from WaitForResources to WaitForResources */
1115      else if(eState == OMX_StateWaitForResources)
1116      {
1117        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
1118        post_event(OMX_EventError,OMX_ErrorSameState,
1119                   OMX_COMPONENT_GENERATE_EVENT);
1120        eRet = OMX_ErrorSameState;
1121      }
1122      /* Requesting transition from WaitForResources to Executing */
1123      else if(eState == OMX_StateExecuting)
1124      {
1125        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
1126        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1127                   OMX_COMPONENT_GENERATE_EVENT);
1128        eRet = OMX_ErrorIncorrectStateTransition;
1129      }
1130      /* Requesting transition from WaitForResources to Pause */
1131      else if(eState == OMX_StatePause)
1132      {
1133        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
1134        post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1135                   OMX_COMPONENT_GENERATE_EVENT);
1136        eRet = OMX_ErrorIncorrectStateTransition;
1137      }
1138      /* Requesting transition from WaitForResources to Invalid */
1139      else if(eState == OMX_StateInvalid)
1140      {
1141        DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
1142        post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1143        eRet = OMX_ErrorInvalidState;
1144      }
1145      /* Requesting transition from WaitForResources to Loaded -
1146      is NOT tested by Khronos TS */
1147
1148    }
1149    else
1150    {
1151      DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
1152      eRet = OMX_ErrorBadParameter;
1153    }
1154  }
1155  /********************************/
1156  /* Current State is Invalid */
1157  /*******************************/
1158  else if(m_state == OMX_StateInvalid)
1159  {
1160    /* State Transition from Inavlid to any state */
1161    if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
1162                  || OMX_StateIdle || OMX_StateExecuting
1163                  || OMX_StatePause || OMX_StateInvalid))
1164    {
1165      DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
1166      post_event(OMX_EventError,OMX_ErrorInvalidState,\
1167                 OMX_COMPONENT_GENERATE_EVENT);
1168      eRet = OMX_ErrorInvalidState;
1169    }
1170  }
1171  else if(cmd == OMX_CommandFlush)
1172  {
1173    if(0 == param1 || OMX_ALL == param1)
1174    {
1175      BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1176    }
1177    if(1 == param1 || OMX_ALL == param1)
1178    {
1179      //generate output flush event only.
1180      BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1181    }
1182
1183    execute_omx_flush(param1);
1184    bFlag = 0;
1185  }
1186  else if( cmd == OMX_CommandPortEnable)
1187  {
1188    if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1189    {
1190      m_sInPortDef.bEnabled = OMX_TRUE;
1191
1192      if( (m_state == OMX_StateLoaded &&
1193           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1194          || allocate_input_done())
1195      {
1196        post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
1197                   OMX_COMPONENT_GENERATE_EVENT);
1198      }
1199      else
1200      {
1201        DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1202        BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1203        // Skip the event notification
1204        bFlag = 0;
1205      }
1206    }
1207    if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1208    {
1209      m_sOutPortDef.bEnabled = OMX_TRUE;
1210
1211      if( (m_state == OMX_StateLoaded &&
1212           !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1213          || (allocate_output_done()))
1214      {
1215        post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
1216                   OMX_COMPONENT_GENERATE_EVENT);
1217
1218      }
1219      else
1220      {
1221        DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1222        BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1223        // Skip the event notification
1224        bFlag = 0;
1225      }
1226    }
1227  }
1228  else if(cmd == OMX_CommandPortDisable)
1229  {
1230    if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1231    {
1232      m_sInPortDef.bEnabled = OMX_FALSE;
1233      if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1234         && release_input_done())
1235      {
1236        post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
1237                   OMX_COMPONENT_GENERATE_EVENT);
1238      }
1239      else
1240      {
1241        BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1242        if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1243        {
1244          execute_omx_flush(PORT_INDEX_IN);
1245        }
1246
1247        // Skip the event notification
1248        bFlag = 0;
1249      }
1250    }
1251    if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1252    {
1253      m_sOutPortDef.bEnabled = OMX_FALSE;
1254
1255      if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1256         && release_output_done())
1257      {
1258        post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
1259                   OMX_COMPONENT_GENERATE_EVENT);
1260      }
1261      else
1262      {
1263        BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1264        if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1265        {
1266          execute_omx_flush(PORT_INDEX_OUT);
1267        }
1268        // Skip the event notification
1269        bFlag = 0;
1270
1271      }
1272    }
1273  }
1274  else
1275  {
1276    DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
1277    eRet = OMX_ErrorNotImplemented;
1278  }
1279  if(eRet == OMX_ErrorNone && bFlag)
1280  {
1281    post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1282  }
1283  sem_post(&m_cmd_lock);
1284  return eRet;
1285}
1286
1287/* ======================================================================
1288FUNCTION
1289  omx_venc::ExecuteOmxFlush
1290
1291DESCRIPTION
1292  Executes the OMX flush.
1293
1294PARAMETERS
1295  flushtype - input flush(1)/output flush(0)/ both.
1296
1297RETURN VALUE
1298  true/false
1299
1300========================================================================== */
1301bool omx_video::execute_omx_flush(OMX_U32 flushType)
1302{
1303  bool bRet = false;
1304  DEBUG_PRINT_LOW("\n execute_omx_flush -  %d\n", flushType);
1305  if(flushType == 0 || flushType == OMX_ALL)
1306  {
1307    input_flush_progress = true;
1308    //flush input only
1309    bRet = execute_input_flush();
1310  }
1311  if(flushType == 1 || flushType == OMX_ALL)
1312  {
1313    //flush output only
1314    output_flush_progress = true;
1315    bRet = execute_output_flush();
1316  }
1317  return bRet;
1318}
1319/*=========================================================================
1320FUNCTION : execute_output_flush
1321
1322DESCRIPTION
1323  Executes the OMX flush at OUTPUT PORT.
1324
1325PARAMETERS
1326  None.
1327
1328RETURN VALUE
1329  true/false
1330==========================================================================*/
1331bool omx_video::execute_output_flush(void)
1332{
1333  unsigned      p1 = 0; // Parameter - 1
1334  unsigned      p2 = 0; // Parameter - 2
1335  unsigned      ident = 0;
1336  bool bRet = true;
1337
1338  /*Generate FBD for all Buffers in the FTBq*/
1339  DEBUG_PRINT_LOW("\n execute_output_flush\n");
1340  pthread_mutex_lock(&m_lock);
1341  while(m_ftb_q.m_size)
1342  {
1343    m_ftb_q.pop_entry(&p1,&p2,&ident);
1344
1345    if(ident == OMX_COMPONENT_GENERATE_FTB )
1346    {
1347      pending_output_buffers++;
1348      fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1349    }
1350    else if(ident == OMX_COMPONENT_GENERATE_FBD)
1351    {
1352      fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1353    }
1354  }
1355
1356  pthread_mutex_unlock(&m_lock);
1357  /*Check if there are buffers with the Driver*/
1358  if(dev_flush(PORT_INDEX_OUT))
1359  {
1360    DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
1361    return false;
1362  }
1363
1364  return bRet;
1365}
1366/*=========================================================================
1367FUNCTION : execute_input_flush
1368
1369DESCRIPTION
1370  Executes the OMX flush at INPUT PORT.
1371
1372PARAMETERS
1373  None.
1374
1375RETURN VALUE
1376  true/false
1377==========================================================================*/
1378bool omx_video::execute_input_flush(void)
1379{
1380  unsigned      p1 = 0; // Parameter - 1
1381  unsigned      p2 = 0; // Parameter - 2
1382  unsigned      ident = 0;
1383  bool bRet = true;
1384
1385  /*Generate EBD for all Buffers in the ETBq*/
1386  DEBUG_PRINT_LOW("\n execute_input_flush\n");
1387
1388  pthread_mutex_lock(&m_lock);
1389  while(m_etb_q.m_size)
1390  {
1391    m_etb_q.pop_entry(&p1,&p2,&ident);
1392    if(ident == OMX_COMPONENT_GENERATE_ETB)
1393    {
1394      pending_input_buffers++;
1395      empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1396    }
1397    else if(ident == OMX_COMPONENT_GENERATE_EBD)
1398    {
1399      empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1400    }
1401    else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ)
1402    {
1403      m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1404    }
1405  }
1406  if(mUseProxyColorFormat) {
1407    if(psource_frame) {
1408      m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1409      psource_frame = NULL;
1410    }
1411    while(m_opq_meta_q.m_size) {
1412      unsigned p1,p2,id;
1413      m_opq_meta_q.pop_entry(&p1,&p2,&id);
1414      m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1415         (OMX_BUFFERHEADERTYPE  *)p1);
1416    }
1417    if(pdest_frame){
1418      m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0);
1419      pdest_frame = NULL;
1420    }
1421  }
1422  pthread_mutex_unlock(&m_lock);
1423  /*Check if there are buffers with the Driver*/
1424  if(dev_flush(PORT_INDEX_IN))
1425  {
1426    DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
1427    return false;
1428  }
1429
1430  return bRet;
1431}
1432
1433
1434/* ======================================================================
1435FUNCTION
1436  omx_venc::SendCommandEvent
1437
1438DESCRIPTION
1439  Send the event to decoder pipe.  This is needed to generate the callbacks
1440  in decoder thread context.
1441
1442PARAMETERS
1443  None.
1444
1445RETURN VALUE
1446  true/false
1447
1448========================================================================== */
1449bool omx_video::post_event(unsigned int p1,
1450                           unsigned int p2,
1451                           unsigned int id)
1452{
1453  bool bRet      =                      false;
1454
1455
1456  pthread_mutex_lock(&m_lock);
1457
1458  if( id == OMX_COMPONENT_GENERATE_FTB || \
1459      (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
1460  {
1461    m_ftb_q.insert_entry(p1,p2,id);
1462  }
1463  else if((id == m_input_msg_id) \
1464          || (id == OMX_COMPONENT_GENERATE_EBD))
1465  {
1466    m_etb_q.insert_entry(p1,p2,id);
1467  }
1468  else
1469  {
1470    m_cmd_q.insert_entry(p1,p2,id);
1471  }
1472
1473  bRet = true;
1474  DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
1475  post_message(this, id);
1476  pthread_mutex_unlock(&m_lock);
1477
1478  return bRet;
1479}
1480
1481/* ======================================================================
1482FUNCTION
1483  omx_venc::GetParameter
1484
1485DESCRIPTION
1486  OMX Get Parameter method implementation
1487
1488PARAMETERS
1489  <TBD>.
1490
1491RETURN VALUE
1492  Error None if successful.
1493
1494========================================================================== */
1495OMX_ERRORTYPE  omx_video::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
1496                                        OMX_IN OMX_INDEXTYPE paramIndex,
1497                                        OMX_INOUT OMX_PTR     paramData)
1498{
1499  OMX_ERRORTYPE eRet = OMX_ErrorNone;
1500  unsigned int height=0,width = 0;
1501
1502  DEBUG_PRINT_LOW("get_parameter: \n");
1503  if(m_state == OMX_StateInvalid)
1504  {
1505    DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
1506    return OMX_ErrorInvalidState;
1507  }
1508  if(paramData == NULL)
1509  {
1510    DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
1511    return OMX_ErrorBadParameter;
1512  }
1513  switch(paramIndex)
1514  {
1515  case OMX_IndexParamPortDefinition:
1516    {
1517      OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1518      portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1519
1520      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
1521      if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1522      {
1523        DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
1524            m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
1525            m_sInPortDef.nBufferCountActual);
1526        memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
1527#ifdef _ANDROID_ICS_
1528        if(meta_mode_enable)
1529        {
1530          portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
1531        }
1532        if(secure_session) {
1533          portDefn->format.video.eColorFormat =
1534            (OMX_COLOR_FORMATTYPE)secure_color_format;
1535        }
1536        else if (mUseProxyColorFormat) {
1537            portDefn->format.video.eColorFormat =
1538              (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1539        }
1540#endif
1541      }
1542      else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1543      {
1544        dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
1545                         &m_sOutPortDef.nBufferCountActual,
1546                         &m_sOutPortDef.nBufferSize,
1547                         m_sOutPortDef.nPortIndex);
1548        DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
1549            m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
1550            m_sOutPortDef.nBufferCountActual);
1551        memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
1552      }
1553      else
1554      {
1555        DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1556        eRet = OMX_ErrorBadPortIndex;
1557      }
1558      break;
1559    }
1560  case OMX_IndexParamVideoInit:
1561    {
1562      OMX_PORT_PARAM_TYPE *portParamType =
1563      (OMX_PORT_PARAM_TYPE *) paramData;
1564      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
1565
1566      memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
1567      break;
1568    }
1569  case OMX_IndexParamVideoPortFormat:
1570    {
1571      OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
1572      (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1573      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
1574
1575      if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1576      {
1577          int index = portFmt->nIndex;
1578
1579          if (index > 1) {
1580              eRet = OMX_ErrorNoMore;
1581          } else {
1582              memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
1583#ifdef _ANDROID_ICS_
1584              if (index == 1) {
1585                  //we support two formats
1586                  //index 0 - YUV420SP
1587                  //index 1 - opaque which internally maps to YUV420SP.
1588                  //this can be extended in the future
1589                  portFmt->nIndex = index; //restore index set from client
1590                  portFmt->eColorFormat =
1591                    (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1592              }
1593          }
1594#endif
1595      }
1596      else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1597      {
1598        memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
1599      }
1600      else
1601      {
1602        DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1603        eRet = OMX_ErrorBadPortIndex;
1604      }
1605      break;
1606    }
1607  case OMX_IndexParamVideoBitrate:
1608    {
1609      OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1610      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
1611
1612      if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1613      {
1614        memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
1615      }
1616      else
1617      {
1618        DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1619        eRet = OMX_ErrorBadPortIndex;
1620      }
1621
1622      break;
1623    }
1624  case OMX_IndexParamVideoMpeg4:
1625    {
1626      OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1627      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
1628      memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
1629      break;
1630    }
1631  case OMX_IndexParamVideoH263:
1632    {
1633      OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1634      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
1635      memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
1636      break;
1637    }
1638  case OMX_IndexParamVideoAvc:
1639    {
1640      OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1641      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
1642      memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
1643      break;
1644    }
1645  case OMX_IndexParamVideoProfileLevelQuerySupported:
1646    {
1647      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1648      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
1649      eRet = get_supported_profile_level(pParam);
1650      if(eRet)
1651        DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
1652                          pParam->eProfile, pParam->eLevel);
1653      break;
1654     }
1655  case OMX_IndexParamVideoProfileLevelCurrent:
1656    {
1657      OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1658      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
1659      memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
1660      break;
1661    }
1662    /*Component should support this port definition*/
1663  case OMX_IndexParamAudioInit:
1664    {
1665      OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1666      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
1667      memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
1668      break;
1669    }
1670    /*Component should support this port definition*/
1671  case OMX_IndexParamImageInit:
1672    {
1673      OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1674      DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
1675      memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
1676      break;
1677
1678    }
1679    /*Component should support this port definition*/
1680  case OMX_IndexParamOtherInit:
1681    {
1682      DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
1683      eRet =OMX_ErrorUnsupportedIndex;
1684      break;
1685    }
1686  case OMX_IndexParamStandardComponentRole:
1687    {
1688      OMX_PARAM_COMPONENTROLETYPE *comp_role;
1689      comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1690      comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
1691      comp_role->nSize = sizeof(*comp_role);
1692
1693      DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
1694      if(NULL != comp_role->cRole)
1695      {
1696        strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
1697      }
1698      else
1699      {
1700        DEBUG_PRINT_ERROR("ERROR: Getparameter: OMX_IndexParamStandardComponentRole %d is passed with NULL parameter for role\n",paramIndex);
1701        eRet =OMX_ErrorBadParameter;
1702      }
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_QcomIndexParamVideoEncodeMetaBufferMode;
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 = bytes;
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,ION_FLAG_CACHED);
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          = bytes;
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 && (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        return OMX_ErrorBadParameter;
4071      }
4072    }
4073  } else if(m_pCallbacks.EmptyBufferDone) {
4074    m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4075  }
4076  return OMX_ErrorNone;
4077}
4078
4079void omx_video::complete_pending_buffer_done_cbs()
4080{
4081  unsigned p1;
4082  unsigned p2;
4083  unsigned ident;
4084  omx_cmd_queue tmp_q, pending_bd_q;
4085  pthread_mutex_lock(&m_lock);
4086  // pop all pending GENERATE FDB from ftb queue
4087  while (m_ftb_q.m_size)
4088  {
4089    m_ftb_q.pop_entry(&p1,&p2,&ident);
4090    if(ident == OMX_COMPONENT_GENERATE_FBD)
4091    {
4092      pending_bd_q.insert_entry(p1,p2,ident);
4093    }
4094    else
4095    {
4096      tmp_q.insert_entry(p1,p2,ident);
4097    }
4098  }
4099  //return all non GENERATE FDB to ftb queue
4100  while(tmp_q.m_size)
4101  {
4102    tmp_q.pop_entry(&p1,&p2,&ident);
4103    m_ftb_q.insert_entry(p1,p2,ident);
4104  }
4105  // pop all pending GENERATE EDB from etb queue
4106  while (m_etb_q.m_size)
4107  {
4108    m_etb_q.pop_entry(&p1,&p2,&ident);
4109    if(ident == OMX_COMPONENT_GENERATE_EBD)
4110    {
4111      pending_bd_q.insert_entry(p1,p2,ident);
4112    }
4113    else
4114    {
4115      tmp_q.insert_entry(p1,p2,ident);
4116    }
4117  }
4118  //return all non GENERATE FDB to etb queue
4119  while(tmp_q.m_size)
4120  {
4121    tmp_q.pop_entry(&p1,&p2,&ident);
4122    m_etb_q.insert_entry(p1,p2,ident);
4123  }
4124  pthread_mutex_unlock(&m_lock);
4125  // process all pending buffer dones
4126  while(pending_bd_q.m_size)
4127  {
4128    pending_bd_q.pop_entry(&p1,&p2,&ident);
4129    switch(ident)
4130    {
4131    case OMX_COMPONENT_GENERATE_EBD:
4132        if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
4133        {
4134          DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
4135          omx_report_error ();
4136        }
4137        break;
4138
4139      case OMX_COMPONENT_GENERATE_FBD:
4140        if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
4141        {
4142          DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
4143          omx_report_error ();
4144        }
4145        break;
4146    }
4147  }
4148}
4149
4150#ifdef MAX_RES_720P
4151OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4152{
4153  OMX_ERRORTYPE eRet = OMX_ErrorNone;
4154  if(!profileLevelType)
4155    return OMX_ErrorBadParameter;
4156
4157  if(profileLevelType->nPortIndex == 1) {
4158    if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4159    {
4160      if (profileLevelType->nProfileIndex == 0)
4161      {
4162        profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4163        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4164      }
4165      else if (profileLevelType->nProfileIndex == 1)
4166      {
4167        profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4168        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4169      }
4170      else if(profileLevelType->nProfileIndex == 2)
4171      {
4172        profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4173        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
4174      }
4175      else
4176      {
4177        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4178            profileLevelType->nProfileIndex);
4179        eRet = OMX_ErrorNoMore;
4180      }
4181    }
4182    else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4183    {
4184      if (profileLevelType->nProfileIndex == 0)
4185      {
4186        profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4187        profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4188      }
4189      else
4190      {
4191        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4192        eRet = OMX_ErrorNoMore;
4193      }
4194    }
4195    else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4196    {
4197      if (profileLevelType->nProfileIndex == 0)
4198      {
4199        profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4200        profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4201      }
4202      else if(profileLevelType->nProfileIndex == 1)
4203      {
4204        profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4205        profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4206      }
4207      else
4208      {
4209        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4210        eRet = OMX_ErrorNoMore;
4211      }
4212    }
4213  }
4214  else
4215  {
4216    DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4217    eRet = OMX_ErrorBadPortIndex;
4218  }
4219  DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4220                    profileLevelType->eProfile,profileLevelType->eLevel);
4221  return eRet;
4222}
4223#endif
4224
4225#ifdef MAX_RES_1080P
4226OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4227{
4228  OMX_ERRORTYPE eRet = OMX_ErrorNone;
4229  if(!profileLevelType)
4230    return OMX_ErrorBadParameter;
4231
4232  if(profileLevelType->nPortIndex == 1) {
4233    if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4234    {
4235      if (profileLevelType->nProfileIndex == 0)
4236      {
4237        profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4238        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4239
4240      }
4241      else if (profileLevelType->nProfileIndex == 1)
4242      {
4243        profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4244        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4245      }
4246      else if(profileLevelType->nProfileIndex == 2)
4247      {
4248        profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4249        profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
4250      }
4251      else
4252      {
4253        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4254            profileLevelType->nProfileIndex);
4255        eRet = OMX_ErrorNoMore;
4256      }
4257    }
4258    else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4259    {
4260      if (profileLevelType->nProfileIndex == 0)
4261      {
4262        profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4263        profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
4264      }
4265      else
4266      {
4267        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4268        eRet = OMX_ErrorNoMore;
4269      }
4270    }
4271    else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4272    {
4273      if (profileLevelType->nProfileIndex == 0)
4274      {
4275        profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4276        profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4277      }
4278      else if(profileLevelType->nProfileIndex == 1)
4279      {
4280        profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4281        profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
4282      }
4283      else
4284      {
4285        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4286        eRet = OMX_ErrorNoMore;
4287      }
4288    }
4289  }
4290  else
4291  {
4292    DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4293    eRet = OMX_ErrorBadPortIndex;
4294  }
4295  DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4296                    profileLevelType->eProfile,profileLevelType->eLevel);
4297  return eRet;
4298}
4299
4300#ifdef USE_ION
4301int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
4302                                    struct ion_fd_data *fd_data,int flag)
4303{
4304  struct venc_ion buf_ion_info;
4305  int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
4306  if (size <=0 || !alloc_data || !fd_data) {
4307    DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory");
4308    return -EINVAL;
4309	}
4310    ion_dev_flags = O_RDONLY;
4311        ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
4312        if(ion_device_fd < 0)
4313        {
4314           DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
4315           return ion_device_fd;
4316        }
4317        alloc_data->len = size;
4318        alloc_data->align = 4096;
4319        alloc_data->flags = 0;
4320        if(!secure_session && (flag & ION_FLAG_CACHED))
4321        {
4322          alloc_data->flags = ION_FLAG_CACHED;
4323        }
4324
4325        if (secure_session)
4326           alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
4327        else
4328           alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) |
4329                ION_HEAP(ION_IOMMU_HEAP_ID));
4330
4331        rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
4332        if(rc || !alloc_data->handle) {
4333           DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
4334           alloc_data->handle =NULL;
4335           close(ion_device_fd);
4336           ion_device_fd = -1;
4337           return ion_device_fd;
4338        }
4339        fd_data->handle = alloc_data->handle;
4340        rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
4341        if(rc) {
4342            DEBUG_PRINT_ERROR("\n ION MAP failed ");
4343            buf_ion_info.ion_alloc_data = *alloc_data;
4344            buf_ion_info.ion_device_fd = ion_device_fd;
4345            buf_ion_info.fd_ion_data = *fd_data;
4346            free_ion_memory(&buf_ion_info);
4347            fd_data->fd =-1;
4348            ion_device_fd =-1;
4349        }
4350        return ion_device_fd;
4351}
4352
4353void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
4354{
4355     if (!buf_ion_info) {
4356        DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory");
4357        return;
4358     }
4359     if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
4360              &buf_ion_info->ion_alloc_data.handle)) {
4361         DEBUG_PRINT_ERROR("\n ION free failed ");
4362         return;
4363     }
4364     close(buf_ion_info->ion_device_fd);
4365     buf_ion_info->ion_alloc_data.handle = NULL;
4366     buf_ion_info->ion_device_fd = -1;
4367     buf_ion_info->fd_ion_data.fd = -1;
4368}
4369#endif
4370#endif
4371#ifdef _ANDROID_ICS_
4372void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
4373{
4374  if(buffer && meta_mode_enable)
4375  {
4376    encoder_media_buffer_type *media_ptr;
4377    struct pmem Input_pmem;
4378    unsigned int index_pmem = 0;
4379    bool meta_error = false;
4380
4381    index_pmem = (buffer - m_inp_mem_ptr);
4382    if(mUseProxyColorFormat &&
4383       (index_pmem < m_sInPortDef.nBufferCountActual)) {
4384        if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){
4385          DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed");
4386        }
4387    } else {
4388      media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
4389      if(media_ptr && media_ptr->meta_handle)
4390      {
4391        if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
4392           media_ptr->meta_handle->numFds == 1 &&
4393           media_ptr->meta_handle->numInts == 2) {
4394          Input_pmem.fd = media_ptr->meta_handle->data[0];
4395          Input_pmem.buffer = media_ptr;
4396          Input_pmem.size = media_ptr->meta_handle->data[2];
4397          Input_pmem.offset = media_ptr->meta_handle->data[1];
4398          DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
4399                            Input_pmem.offset,
4400                            Input_pmem.size);
4401        } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
4402          private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
4403          Input_pmem.buffer = media_ptr;
4404          Input_pmem.fd = handle->fd;
4405          Input_pmem.offset = 0;
4406          Input_pmem.size = handle->size;
4407        } else {
4408          meta_error = true;
4409          DEBUG_PRINT_ERROR(" Meta Error set in EBD");
4410        }
4411        if(!meta_error)
4412           meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
4413          if(meta_error)
4414          {
4415           DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
4416               input_flush_progress);
4417          }
4418        }
4419     }
4420  }
4421}
4422#endif
4423omx_video::omx_c2d_conv::omx_c2d_conv()
4424{
4425  c2dcc = NULL;
4426  mLibHandle = NULL;
4427  mConvertOpen = NULL;
4428  mConvertClose = NULL;
4429  src_format = NV12_2K;
4430}
4431
4432bool omx_video::omx_c2d_conv::init() {
4433  bool status = true;
4434  if(mLibHandle || mConvertOpen || mConvertClose) {
4435    DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice");
4436    status = false;
4437  }
4438  if(status) {
4439    mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
4440    if(mLibHandle){
4441       mConvertOpen = (createC2DColorConverter_t *)
4442       dlsym(mLibHandle,"createC2DColorConverter");
4443       mConvertClose = (destroyC2DColorConverter_t *)
4444       dlsym(mLibHandle,"destroyC2DColorConverter");
4445       if(!mConvertOpen || !mConvertClose)
4446         status = false;
4447    } else
4448      status = false;
4449  }
4450  if(!status && mLibHandle){
4451    dlclose(mLibHandle);
4452    mLibHandle = NULL;
4453    mConvertOpen = NULL;
4454    mConvertClose = NULL;
4455  }
4456  return status;
4457}
4458
4459bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_viraddr,
4460     int dest_fd,void *dest_viraddr)
4461{
4462  int result;
4463  if(!src_viraddr || !dest_viraddr || !c2dcc){
4464    DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert");
4465    return false;
4466  }
4467  result =  c2dcc->convertC2D(src_fd,src_viraddr,
4468                              dest_fd,dest_viraddr);
4469  DEBUG_PRINT_LOW("\n Color convert status %d",result);
4470  return ((result < 0)?false:true);
4471}
4472
4473bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
4474     ColorConvertFormat src, ColorConvertFormat dest)
4475{
4476  bool status = false;
4477  if(!c2dcc) {
4478     c2dcc = mConvertOpen(width, height, width, height,
4479             src,dest,0);
4480     if(c2dcc) {
4481       src_format = src;
4482       status = true;
4483     } else
4484       DEBUG_PRINT_ERROR("\n mConvertOpen failed");
4485  }
4486   return status;
4487}
4488void omx_video::omx_c2d_conv::close()
4489{
4490  if(mLibHandle) {
4491    if(mConvertClose && c2dcc)
4492     mConvertClose(c2dcc);
4493    c2dcc = NULL;
4494  }
4495}
4496omx_video::omx_c2d_conv::~omx_c2d_conv()
4497{
4498  DEBUG_PRINT_ERROR("\n Destroy C2D instance");
4499  if(mLibHandle) {
4500    if(mConvertClose && c2dcc)
4501      mConvertClose(c2dcc);
4502    dlclose(mLibHandle);
4503  }
4504  c2dcc = NULL;
4505  mLibHandle = NULL;
4506  mConvertOpen = NULL;
4507  mConvertClose = NULL;
4508}
4509int omx_video::omx_c2d_conv::get_src_format()
4510{
4511  int format = -1;
4512  if(src_format == NV12_2K) {
4513    format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
4514  } else if(src_format == RGBA8888) {
4515    format = HAL_PIXEL_FORMAT_RGBA_8888;
4516  }
4517  return format;
4518}
4519bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
4520{
4521  int cret = 0;
4522  bool ret = false;
4523  C2DBuffReq bufferreq;
4524  if(c2dcc){
4525    bufferreq.size = 0;
4526    cret = c2dcc->getBuffReq(port,&bufferreq);
4527    DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret);
4528    ret = (cret)?false:true;
4529    buf_size = bufferreq.size;
4530  }
4531  return ret;
4532}
4533OMX_ERRORTYPE  omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
4534                                                  OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4535{
4536  unsigned nBufIndex = 0;
4537  OMX_ERRORTYPE ret = OMX_ErrorNone;
4538  encoder_media_buffer_type *media_buffer;
4539  DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer);
4540
4541  if(buffer == NULL) {
4542    DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer);
4543    return OMX_ErrorBadParameter;
4544  }
4545  nBufIndex = buffer - meta_buffer_hdr;
4546  if(nBufIndex >= m_sInPortDef.nBufferCountActual) {
4547    DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n",
4548                      nBufIndex);
4549    return OMX_ErrorBadParameter;
4550  }
4551  media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
4552  private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4553  /*Enable following code once private handle color format is
4554    updated correctly*/
4555
4556  if(buffer->nFilledLen > 0) {
4557    if(c2d_opened && handle->format != c2d_conv.get_src_format()) {
4558      c2d_conv.close();
4559      c2d_opened = false;
4560    }
4561    if (!c2d_opened) {
4562        if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
4563          DEBUG_PRINT_ERROR("\n open Color conv for RGBA888");
4564          if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
4565               m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K)){
4566             m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4567             DEBUG_PRINT_ERROR("\n Color conv open failed");
4568             return OMX_ErrorBadParameter;
4569          }
4570          c2d_opened = true;
4571        } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
4572          DEBUG_PRINT_ERROR("\n Incorrect color format");
4573          m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4574          return OMX_ErrorBadParameter;
4575        }
4576    }
4577  }
4578
4579  if(input_flush_progress == true)
4580  {
4581    m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4582    DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress");
4583    return OMX_ErrorNone;
4584  }
4585
4586  if(!psource_frame) {
4587    psource_frame = buffer;
4588    ret = push_input_buffer(hComp);
4589  } else {
4590    if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) {
4591      DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full");
4592      ret = OMX_ErrorBadParameter;
4593    }
4594  }
4595  if(ret != OMX_ErrorNone) {
4596    m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4597    DEBUG_PRINT_LOW("\nERROR: ETBOpaque failed:");
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  }
4631  return ret;
4632}
4633
4634OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
4635     struct pmem &Input_pmem_info,unsigned &index){
4636
4637  unsigned char *uva;
4638  OMX_ERRORTYPE ret = OMX_ErrorNone;
4639  unsigned address = 0,p2,id;
4640
4641  DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer");
4642  if(!psource_frame || !pdest_frame) {
4643    DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4644    return OMX_ErrorBadParameter;
4645  }
4646
4647  if(!psource_frame->nFilledLen){
4648    if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){
4649        pdest_frame->nFilledLen = psource_frame->nFilledLen;
4650        pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4651        pdest_frame->nFlags = psource_frame->nFlags;
4652        DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \
4653          Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen);
4654    } else {
4655        pdest_frame->nOffset = 0;
4656        pdest_frame->nFilledLen = 0;
4657        pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4658        pdest_frame->nFlags = psource_frame->nFlags;
4659        DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4660           pdest_frame,pdest_frame->nFilledLen);
4661    }
4662  } else {
4663     uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
4664                           PROT_READ|PROT_WRITE,
4665                           MAP_SHARED,Input_pmem_info.fd,0);
4666     if(uva == MAP_FAILED) {
4667       ret = OMX_ErrorBadParameter;
4668     } else {
4669       if(!c2d_conv.convert(Input_pmem_info.fd,uva,
4670          m_pInput_pmem[index].fd,pdest_frame->pBuffer)) {
4671          DEBUG_PRINT_ERROR("\n Color Conversion failed");
4672          ret = OMX_ErrorBadParameter;
4673       } else {
4674          unsigned int buf_size = 0;
4675          if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
4676            ret = OMX_ErrorBadParameter;
4677          else {
4678            pdest_frame->nOffset = 0;
4679            if(!buf_size || buf_size > pdest_frame->nAllocLen) {
4680              DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer"
4681               "size mismatch buf size %d alloc size %d",
4682                      buf_size, pdest_frame->nAllocLen);
4683              ret = OMX_ErrorBadParameter;
4684              buf_size = 0;
4685            }
4686            pdest_frame->nFilledLen = buf_size;
4687            pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4688            pdest_frame->nFlags = psource_frame->nFlags;
4689            DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4690               pdest_frame,pdest_frame->nFilledLen);
4691           }
4692         }
4693         munmap(uva,Input_pmem_info.size);
4694      }
4695    }
4696    if((ret == OMX_ErrorNone) &&
4697       dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
4698      DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4699      post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
4700      ret = OMX_ErrorBadParameter;
4701    }
4702    if(ret == OMX_ErrorNone)
4703      ret = empty_this_buffer_proxy(hComp,pdest_frame);
4704    if(ret == OMX_ErrorNone) {
4705      m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
4706      psource_frame = NULL;
4707      pdest_frame = NULL;
4708      if(!psource_frame && m_opq_meta_q.m_size) {
4709        m_opq_meta_q.pop_entry(&address,&p2,&id);
4710        psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4711      }
4712      if(!pdest_frame && m_opq_pmem_q.m_size) {
4713        m_opq_pmem_q.pop_entry(&address,&p2,&id);
4714        pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4715        DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame);
4716      }
4717    }
4718    return ret;
4719}
4720
4721OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
4722{
4723  unsigned address = 0,p2,id, index = 0;
4724  OMX_ERRORTYPE ret = OMX_ErrorNone;
4725
4726  if(!psource_frame && m_opq_meta_q.m_size) {
4727    m_opq_meta_q.pop_entry(&address,&p2,&id);
4728    psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4729  }
4730  if(!pdest_frame && m_opq_pmem_q.m_size) {
4731    m_opq_pmem_q.pop_entry(&address,&p2,&id);
4732    pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4733  }
4734  while(psource_frame != NULL && pdest_frame != NULL &&
4735        ret == OMX_ErrorNone) {
4736    struct pmem Input_pmem_info;
4737    encoder_media_buffer_type *media_buffer;
4738    index = pdest_frame - m_inp_mem_ptr;
4739    if(index >= m_sInPortDef.nBufferCountActual){
4740       DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d",
4741                         index,m_sInPortDef.nBufferCountActual);
4742       return OMX_ErrorBadParameter;
4743    }
4744    media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
4745    /*Will enable to verify camcorder in current TIPS can be removed*/
4746    if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
4747      Input_pmem_info.buffer = media_buffer;
4748      Input_pmem_info.fd = media_buffer->meta_handle->data[0];
4749      Input_pmem_info.offset = media_buffer->meta_handle->data[1];
4750      Input_pmem_info.size = media_buffer->meta_handle->data[2];
4751      DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
4752                        Input_pmem_info.offset,
4753                        Input_pmem_info.size);
4754      ret = queue_meta_buffer(hComp,Input_pmem_info);
4755    } else if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) {
4756       ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4757    } else {
4758      private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4759      Input_pmem_info.buffer = media_buffer;
4760      Input_pmem_info.fd = handle->fd;
4761      Input_pmem_info.offset = 0;
4762      Input_pmem_info.size = handle->size;
4763      if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
4764        ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4765      else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
4766        ret = queue_meta_buffer(hComp,Input_pmem_info);
4767      else
4768        ret = OMX_ErrorBadParameter;
4769    }
4770   }
4771  return ret;
4772}
4773