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