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