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