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