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