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