1/*--------------------------------------------------------------------------
2Copyright (c) 2010 - 2013, The Linux Foundation. All rights reserved.
3
4  Redistribution and use in source and binary forms, with or without
5  modification, are permitted provided that the following conditions
6  are met:
7
8    * Redistributions of source code must retain the above copyright
9  notice, this list of conditions and the following disclaimer.
10    * Redistributions in binary form must reproduce the above
11  copyright notice, this list of conditions and the following
12      disclaimer in the documentation and/or other materials provided
13      with the distribution.
14    * Neither the name of The Linux Foundation nor the names of its
15      contributors may be used to endorse or promote products derived
16      from this software without specific prior written permission.
17
18THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
19WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
21ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
22BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
25BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
27OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
28IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29--------------------------------------------------------------------------*/
30
31/*============================================================================
32                            O p e n M A X   w r a p p e r s
33                             O p e n  M A X   C o r e
34
35*//** @file omx_vdec.cpp
36  This module contains the implementation of the OpenMAX core & component.
37
38*//*========================================================================*/
39
40//////////////////////////////////////////////////////////////////////////////
41//                             Include Files
42//////////////////////////////////////////////////////////////////////////////
43#define JB_MR1
44#include <string.h>
45#include <pthread.h>
46#include <sys/prctl.h>
47#include <stdlib.h>
48#include <unistd.h>
49#include <errno.h>
50#ifndef JB_MR1
51#include <ihwc.h>
52#include <binder/IServiceManager.h>
53#endif
54#include "power_module.h"
55#include "omx_vdec.h"
56#include <fcntl.h>
57#include <limits.h>
58
59#ifndef _ANDROID_
60#include <sys/ioctl.h>
61#include <sys/mman.h>
62#endif //_ANDROID_
63
64#ifdef _ANDROID_
65#include <cutils/properties.h>
66#undef USE_EGL_IMAGE_GPU
67#endif
68
69#if  defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
70#include <gralloc_priv.h>
71#endif
72
73#if defined (_ANDROID_ICS_)
74#include <genlock.h>
75#include <qdMetaData.h>
76#endif
77
78#ifdef _ANDROID_
79#include "DivXDrmDecrypt.h"
80#endif //_ANDROID_
81
82#ifdef USE_EGL_IMAGE_GPU
83#include <EGL/egl.h>
84#include <EGL/eglQCOM.h>
85#define EGL_BUFFER_HANDLE_QCOM 0x4F00
86#define EGL_BUFFER_OFFSET_QCOM 0x4F01
87#endif
88
89#ifdef INPUT_BUFFER_LOG
90#define INPUT_BUFFER_FILE_NAME "/data/input-bitstream.\0\0\0\0"
91#define INPUT_BUFFER_FILE_NAME_LEN 30
92FILE *inputBufferFile1;
93char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
94#endif
95#ifdef OUTPUT_BUFFER_LOG
96FILE *outputBufferFile1;
97char outputfilename [] = "/data/output.yuv";
98#endif
99#ifdef OUTPUT_EXTRADATA_LOG
100FILE *outputExtradataFile;
101char ouputextradatafilename [] = "/data/extradata";
102#endif
103
104#define DEFAULT_FPS 30
105#define MAX_NUM_SPS 32
106#define MAX_NUM_PPS 256
107#define MAX_INPUT_ERROR (MAX_NUM_SPS + MAX_NUM_PPS)
108#define MAX_SUPPORTED_FPS 120
109
110#define VC1_SP_MP_START_CODE        0xC5000000
111#define VC1_SP_MP_START_CODE_MASK   0xFF000000
112#define VC1_AP_SEQ_START_CODE       0x0F010000
113#define VC1_STRUCT_C_PROFILE_MASK   0xF0
114#define VC1_STRUCT_B_LEVEL_MASK     0xE0000000
115#define VC1_SIMPLE_PROFILE          0
116#define VC1_MAIN_PROFILE            1
117#define VC1_ADVANCE_PROFILE         3
118#define VC1_SIMPLE_PROFILE_LOW_LEVEL  0
119#define VC1_SIMPLE_PROFILE_MED_LEVEL  2
120#define VC1_STRUCT_C_LEN            4
121#define VC1_STRUCT_C_POS            8
122#define VC1_STRUCT_A_POS            12
123#define VC1_STRUCT_B_POS            24
124#define VC1_SEQ_LAYER_SIZE          36
125
126#ifdef USE_ION
127#define MEM_DEVICE "/dev/ion"
128#ifdef MAX_RES_720P
129#define MEM_HEAP_ID ION_CAMERA_HEAP_ID
130#else
131#define MEM_HEAP_ID ION_CP_MM_HEAP_ID
132#endif
133#elif MAX_RES_720P
134#define MEM_DEVICE "/dev/pmem_adsp"
135#elif MAX_RES_1080P_EBI
136#define MEM_DEVICE "/dev/pmem_adsp"
137#elif MAX_RES_1080P
138#define MEM_DEVICE "/dev/pmem_smipool"
139#endif
140
141
142#ifdef MAX_RES_720P
143#define DEVICE_SCRATCH 0
144#else
145#define DEVICE_SCRATCH 64
146#endif
147
148/*
149#ifdef _ANDROID_
150extern "C"{
151#include<utils/Log.h>
152}
153#endif//_ANDROID_
154 */
155
156#ifndef _ANDROID_
157#include <glib.h>
158#define strlcpy g_strlcpy
159#endif
160
161#define Log2(number, power)  { OMX_U32 temp = number; power = 0; while( (0 == (temp & 0x1)) &&  power < 16) { temp >>=0x1; power++; } }
162#define Q16ToFraction(q,num,den) { OMX_U32 power; Log2(q,power);  num = q >> power; den = 0x1 << (16 - power); }
163
164void* async_message_thread (void *input)
165{
166    struct vdec_ioctl_msg ioctl_msg;
167    struct vdec_msginfo vdec_msg;
168    omx_vdec *omx = reinterpret_cast<omx_vdec*>(input);
169    int error_code = 0;
170    DEBUG_PRINT_HIGH("omx_vdec: Async thread start");
171    prctl(PR_SET_NAME, (unsigned long)"VideoDecCallBackThread", 0, 0, 0);
172
173    while (1) {
174        ioctl_msg.in = NULL;
175        ioctl_msg.out = (void*)&vdec_msg;
176        /*Wait for a message from the video decoder driver*/
177        error_code = ioctl ( omx->drv_ctx.video_driver_fd,VDEC_IOCTL_GET_NEXT_MSG,
178                (void*)&ioctl_msg);
179
180        if (error_code == -512) { // ERESTARTSYS
181            DEBUG_PRINT_ERROR("\n ERESTARTSYS received in ioctl read next msg!");
182        } else if (error_code < 0) {
183            DEBUG_PRINT_ERROR("\n Error in ioctl read next msg");
184            break;
185        }        /*Call Instance specific process function*/
186        else if (omx->async_message_process(input,&vdec_msg) < 0) {
187            DEBUG_PRINT_ERROR("\nERROR:Wrong ioctl message");
188        }
189    }
190
191    DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
192    return NULL;
193}
194
195void* message_thread(void *input)
196{
197    omx_vdec* omx = reinterpret_cast<omx_vdec*>(input);
198    unsigned char id;
199    int n;
200
201    DEBUG_PRINT_HIGH("omx_vdec: message thread start");
202    prctl(PR_SET_NAME, (unsigned long)"VideoDecMsgThread", 0, 0, 0);
203
204    while (1) {
205
206        n = read(omx->m_pipe_in, &id, 1);
207
208        if (0 == n) {
209            break;
210        }
211
212        if (1 == n) {
213            omx->process_event_cb(omx, id);
214        }
215
216        if ((n < 0) && (errno != EINTR)) {
217            DEBUG_PRINT_ERROR("\nERROR: read from pipe failed, ret %d errno %d", n, errno);
218            break;
219        }
220    }
221
222    DEBUG_PRINT_HIGH("omx_vdec: message thread stop");
223    return 0;
224}
225
226void post_message(omx_vdec *omx, unsigned char id)
227{
228    int ret_value;
229    DEBUG_PRINT_LOW("omx_vdec: post_message %d pipe out%d", id,omx->m_pipe_out);
230    ret_value = write(omx->m_pipe_out, &id, 1);
231    DEBUG_PRINT_LOW("post_message to pipe done %d",ret_value);
232}
233
234// omx_cmd_queue destructor
235omx_vdec::omx_cmd_queue::~omx_cmd_queue()
236{
237    // Nothing to do
238}
239
240// omx cmd queue constructor
241omx_vdec::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
242{
243    memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
244}
245
246// omx cmd queue insert
247bool omx_vdec::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
248{
249    bool ret = true;
250
251    if (m_size < OMX_CORE_CONTROL_CMDQ_SIZE) {
252        m_q[m_write].id       = id;
253        m_q[m_write].param1   = p1;
254        m_q[m_write].param2   = p2;
255        m_write++;
256        m_size ++;
257
258        if (m_write >= OMX_CORE_CONTROL_CMDQ_SIZE) {
259            m_write = 0;
260        }
261    } else {
262        ret = false;
263        DEBUG_PRINT_ERROR("\n ERROR: %s()::Command Queue Full", __func__);
264    }
265
266    return ret;
267}
268
269// omx cmd queue pop
270bool omx_vdec::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
271{
272    bool ret = true;
273
274    if (m_size > 0) {
275        *id = m_q[m_read].id;
276        *p1 = m_q[m_read].param1;
277        *p2 = m_q[m_read].param2;
278        // Move the read pointer ahead
279        ++m_read;
280        --m_size;
281
282        if (m_read >= OMX_CORE_CONTROL_CMDQ_SIZE) {
283            m_read = 0;
284        }
285    } else {
286        ret = false;
287    }
288
289    return ret;
290}
291
292// Retrieve the first mesg type in the queue
293unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
294{
295    return m_q[m_read].id;
296}
297
298#ifdef _ANDROID_
299omx_vdec::ts_arr_list::ts_arr_list()
300{
301    //initialize timestamps array
302    memset(m_ts_arr_list, 0, ( sizeof(ts_entry) * MAX_NUM_INPUT_OUTPUT_BUFFERS) );
303}
304omx_vdec::ts_arr_list::~ts_arr_list()
305{
306    //free m_ts_arr_list?
307}
308
309bool omx_vdec::ts_arr_list::insert_ts(OMX_TICKS ts)
310{
311    bool ret = true;
312    bool duplicate_ts = false;
313    int idx = 0;
314
315    //insert at the first available empty location
316    for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
317        if (!m_ts_arr_list[idx].valid) {
318            //found invalid or empty entry, save timestamp
319            m_ts_arr_list[idx].valid = true;
320            m_ts_arr_list[idx].timestamp = ts;
321            DEBUG_PRINT_LOW("Insert_ts(): Inserting TIMESTAMP (%lld) at idx (%d)",
322                    ts, idx);
323            break;
324        }
325    }
326
327    if (idx == MAX_NUM_INPUT_OUTPUT_BUFFERS) {
328        DEBUG_PRINT_LOW("Timestamp array list is FULL. Unsuccessful insert");
329        ret = false;
330    }
331
332    return ret;
333}
334
335bool omx_vdec::ts_arr_list::pop_min_ts(OMX_TICKS &ts)
336{
337    bool ret = true;
338    int min_idx = -1;
339    OMX_TICKS min_ts = 0;
340    int idx = 0;
341
342    for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
343
344        if (m_ts_arr_list[idx].valid) {
345            //found valid entry, save index
346            if (min_idx < 0) {
347                //first valid entry
348                min_ts = m_ts_arr_list[idx].timestamp;
349                min_idx = idx;
350            } else if (m_ts_arr_list[idx].timestamp < min_ts) {
351                min_ts = m_ts_arr_list[idx].timestamp;
352                min_idx = idx;
353            }
354        }
355
356    }
357
358    if (min_idx < 0) {
359        //no valid entries found
360        DEBUG_PRINT_LOW("Timestamp array list is empty. Unsuccessful pop");
361        ts = 0;
362        ret = false;
363    } else {
364        ts = m_ts_arr_list[min_idx].timestamp;
365        m_ts_arr_list[min_idx].valid = false;
366        DEBUG_PRINT_LOW("Pop_min_ts:Timestamp (%lld), index(%d)",
367                ts, min_idx);
368    }
369
370    return ret;
371
372}
373
374
375bool omx_vdec::ts_arr_list::reset_ts_list()
376{
377    bool ret = true;
378    int idx = 0;
379
380    DEBUG_PRINT_LOW("reset_ts_list(): Resetting timestamp array list");
381
382    for ( ; idx < MAX_NUM_INPUT_OUTPUT_BUFFERS; idx++) {
383        m_ts_arr_list[idx].valid = false;
384    }
385
386    return ret;
387}
388#endif
389
390// factory function executed by the core to create instances
391void *get_omx_component_factory_fn(void)
392{
393    return (new omx_vdec);
394}
395
396#ifdef _ANDROID_
397#ifdef USE_ION
398VideoHeap::VideoHeap(int devicefd, size_t size, void* base,
399        struct ion_handle *handle, int ionMapfd)
400{
401    m_ion_device_fd = devicefd;
402    m_ion_handle = handle;
403    MemoryHeapBase::init(ionMapfd, base, size, 0, MEM_DEVICE);
404    //ionInit(devicefd, base, size, 0 , MEM_DEVICE,handle,ionMapfd);
405}
406#else
407VideoHeap::VideoHeap(int fd, size_t size, void* base)
408{
409    // dup file descriptor, map once, use pmem
410    init(dup(fd), base, size, 0 , MEM_DEVICE);
411}
412#endif
413#endif // _ANDROID_
414/* ======================================================================
415   FUNCTION
416   omx_vdec::omx_vdec
417
418   DESCRIPTION
419   Constructor
420
421   PARAMETERS
422   None
423
424   RETURN VALUE
425   None.
426   ========================================================================== */
427omx_vdec::omx_vdec(): m_state(OMX_StateInvalid),
428    m_app_data(NULL),
429    m_inp_mem_ptr(NULL),
430    m_out_mem_ptr(NULL),
431    m_phdr_pmem_ptr(NULL),
432    pending_input_buffers(0),
433    pending_output_buffers(0),
434    m_out_bm_count(0),
435    m_inp_bm_count(0),
436    m_inp_bPopulated(OMX_FALSE),
437    m_out_bPopulated(OMX_FALSE),
438    m_flags(0),
439    m_inp_bEnabled(OMX_TRUE),
440    m_out_bEnabled(OMX_TRUE),
441    m_platform_list(NULL),
442    m_platform_entry(NULL),
443    m_pmem_info(NULL),
444    output_flush_progress (false),
445    input_flush_progress (false),
446    input_use_buffer (false),
447    output_use_buffer (false),
448    arbitrary_bytes (true),
449    psource_frame (NULL),
450    pdest_frame (NULL),
451    m_inp_heap_ptr (NULL),
452    m_heap_inp_bm_count (0),
453    codec_type_parse ((codec_type)0),
454    first_frame_meta (true),
455    frame_count (0),
456    nal_length(0),
457    nal_count (0),
458    look_ahead_nal (false),
459    first_frame(0),
460    first_buffer(NULL),
461    first_frame_size (0),
462    m_error_propogated(false),
463    m_device_file_ptr(NULL),
464    m_vc1_profile((vc1_profile_type)0),
465    prev_ts(LLONG_MAX),
466    rst_prev_ts(true),
467    frm_int(0),
468    m_in_alloc_cnt(0),
469    m_display_id(NULL),
470    ouput_egl_buffers(false),
471    h264_parser(NULL),
472    client_extradata(0),
473    h264_last_au_ts(LLONG_MAX),
474    h264_last_au_flags(0),
475    m_inp_err_count(0),
476    m_disp_hor_size(0),
477    m_disp_vert_size(0),
478#ifdef _ANDROID_
479    m_heap_ptr(NULL),
480    m_heap_count(0),
481    m_enable_android_native_buffers(OMX_FALSE),
482    m_use_android_native_buffers(OMX_FALSE),
483#endif
484    in_reconfig(false),
485    m_use_output_pmem(OMX_FALSE),
486    m_out_mem_region_smi(OMX_FALSE),
487    m_out_pvt_entry_pmem(OMX_FALSE),
488    secure_mode(false),
489    external_meta_buffer(false),
490    external_meta_buffer_iommu(false)
491#ifdef _ANDROID_
492,iDivXDrmDecrypt(NULL)
493#endif
494    ,m_desc_buffer_ptr(NULL)
495    ,m_extradata(NULL)
496,m_power_hinted(false)
497{
498    /* Assumption is that , to begin with , we have all the frames with decoder */
499    DEBUG_PRINT_HIGH("In OMX vdec Constructor");
500#ifdef _ANDROID_
501    char property_value[PROPERTY_VALUE_MAX] = {0};
502    property_get("vidc.dec.debug.perf", property_value, "0");
503    perf_flag = atoi(property_value);
504
505    if (perf_flag) {
506        DEBUG_PRINT_HIGH("vidc.dec.debug.perf is %d", perf_flag);
507        dec_time.start();
508        proc_frms = latency = 0;
509    }
510
511    property_value[0] = NULL;
512    property_get("vidc.dec.debug.ts", property_value, "0");
513    m_debug_timestamp = atoi(property_value);
514    DEBUG_PRINT_HIGH("vidc.dec.debug.ts value is %d",m_debug_timestamp);
515
516    if (m_debug_timestamp) {
517        time_stamp_dts.set_timestamp_reorder_mode(true);
518        time_stamp_dts.enable_debug_print(true);
519    }
520
521    property_value[0] = NULL;
522    property_get("vidc.dec.debug.concealedmb", property_value, "0");
523    m_debug_concealedmb = atoi(property_value);
524    DEBUG_PRINT_HIGH("vidc.dec.debug.concealedmb value is %d",m_debug_concealedmb);
525
526#endif
527    memset(&m_cmp,0,sizeof(m_cmp));
528    memset(&m_cb,0,sizeof(m_cb));
529    memset (&drv_ctx,0,sizeof(drv_ctx));
530    memset (&h264_scratch,0,sizeof (OMX_BUFFERHEADERTYPE));
531    memset (m_hwdevice_name,0,sizeof(m_hwdevice_name));
532    memset(&op_buf_rcnfg, 0 ,sizeof(vdec_allocatorproperty));
533    memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
534    m_demux_entries = 0;
535    msg_thread_created = false;
536    async_thread_created = false;
537#ifdef _ANDROID_ICS_
538    memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
539#endif
540    drv_ctx.timestamp_adjust = false;
541    drv_ctx.video_driver_fd = -1;
542    m_vendor_config.pData = NULL;
543    pthread_mutex_init(&m_lock, NULL);
544    sem_init(&m_cmd_lock,0,0);
545#ifdef _ANDROID_
546    char extradata_value[PROPERTY_VALUE_MAX] = {0};
547    property_get("vidc.dec.debug.extradata", extradata_value, "0");
548    m_debug_extradata = atoi(extradata_value);
549    DEBUG_PRINT_HIGH("vidc.dec.debug.extradata value is %d",m_debug_extradata);
550#endif
551    m_fill_output_msg = OMX_COMPONENT_GENERATE_FTB;
552    client_buffers.set_vdec_client(this);
553}
554
555
556/* ======================================================================
557   FUNCTION
558   omx_vdec::~omx_vdec
559
560   DESCRIPTION
561   Destructor
562
563   PARAMETERS
564   None
565
566   RETURN VALUE
567   None.
568   ========================================================================== */
569omx_vdec::~omx_vdec()
570{
571    m_pmem_info = NULL;
572    DEBUG_PRINT_HIGH("In OMX vdec Destructor");
573
574    if (m_pipe_in) close(m_pipe_in);
575
576    if (m_pipe_out) close(m_pipe_out);
577
578    m_pipe_in = -1;
579    m_pipe_out = -1;
580
581    if (msg_thread_created) {
582        DEBUG_PRINT_HIGH("Waiting on OMX Msg Thread exit");
583        pthread_join(msg_thread_id,NULL);
584    }
585
586    if (async_thread_created) {
587        DEBUG_PRINT_HIGH("Waiting on OMX Async Thread exit");
588        pthread_join(async_thread_id,NULL);
589    }
590
591    DEBUG_PRINT_HIGH("Calling close() on Video Driver");
592    close (drv_ctx.video_driver_fd);
593    drv_ctx.video_driver_fd = -1;
594
595    pthread_mutex_destroy(&m_lock);
596    sem_destroy(&m_cmd_lock);
597#ifdef _ANDROID_
598
599    if (perf_flag) {
600        DEBUG_PRINT_HIGH("--> TOTAL PROCESSING TIME");
601        dec_time.end();
602    }
603
604#endif /* _ANDROID_ */
605    DEBUG_PRINT_HIGH("Exit OMX vdec Destructor");
606}
607
608/* ======================================================================
609   FUNCTION
610   omx_vdec::OMXCntrlProcessMsgCb
611
612   DESCRIPTION
613   IL Client callbacks are generated through this routine. The decoder
614   provides the thread context for this routine.
615
616   PARAMETERS
617   ctxt -- Context information related to the self.
618   id   -- Event identifier. This could be any of the following:
619   1. Command completion event
620   2. Buffer done callback event
621   3. Frame done callback event
622
623   RETURN VALUE
624   None.
625
626   ========================================================================== */
627void omx_vdec::process_event_cb(void *ctxt, unsigned char id)
628{
629    unsigned p1; // Parameter - 1
630    unsigned p2; // Parameter - 2
631    unsigned ident;
632    unsigned qsize=0; // qsize
633    omx_vdec *pThis = (omx_vdec *) ctxt;
634
635    if (!pThis) {
636        DEBUG_PRINT_ERROR("\n ERROR: %s()::Context is incorrect, bailing out",
637                __func__);
638        return;
639    }
640
641    // Protect the shared queue data structure
642    do {
643        /*Read the message id's from the queue*/
644        pthread_mutex_lock(&pThis->m_lock);
645        qsize = pThis->m_cmd_q.m_size;
646
647        if (qsize) {
648            pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
649        }
650
651        if (qsize == 0 && pThis->m_state != OMX_StatePause) {
652            qsize = pThis->m_ftb_q.m_size;
653
654            if (qsize) {
655                pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
656            }
657        }
658
659        if (qsize == 0 && pThis->m_state != OMX_StatePause) {
660            qsize = pThis->m_etb_q.m_size;
661
662            if (qsize) {
663                pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
664            }
665        }
666
667        pthread_mutex_unlock(&pThis->m_lock);
668
669        /*process message if we have one*/
670        if (qsize > 0) {
671            id = ident;
672
673            switch (id) {
674                case OMX_COMPONENT_GENERATE_EVENT:
675
676                    if (pThis->m_cb.EventHandler) {
677                        switch (p1) {
678                            case OMX_CommandStateSet:
679                                pThis->m_state = (OMX_STATETYPE) p2;
680                                DEBUG_PRINT_HIGH("OMX_CommandStateSet complete, m_state = %d",
681                                        pThis->m_state);
682                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
683                                        OMX_EventCmdComplete, p1, p2, NULL);
684                                break;
685
686                            case OMX_EventError:
687
688                                if (p2 == OMX_StateInvalid) {
689                                    DEBUG_PRINT_ERROR("\n OMX_EventError: p2 is OMX_StateInvalid");
690                                    pThis->m_state = (OMX_STATETYPE) p2;
691                                    pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
692                                            OMX_EventError, OMX_ErrorInvalidState, p2, NULL);
693                                } else if (p2 == OMX_ErrorHardware) {
694                                    pThis->omx_report_error();
695                                } else {
696                                    pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
697                                            OMX_EventError, p2, NULL, NULL );
698                                }
699
700                                break;
701
702                            case OMX_CommandPortDisable:
703                                DEBUG_PRINT_HIGH("OMX_CommandPortDisable complete for port [%d]", p2);
704
705                                if (BITMASK_PRESENT(&pThis->m_flags,
706                                            OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
707                                    BITMASK_SET(&pThis->m_flags, OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
708                                    break;
709                                }
710
711                                if (p2 == OMX_CORE_OUTPUT_PORT_INDEX && pThis->in_reconfig) {
712                                    pThis->in_reconfig = false;
713                                    pThis->drv_ctx.op_buf = pThis->op_buf_rcnfg;
714                                    OMX_ERRORTYPE eRet = pThis->set_buffer_req(&pThis->drv_ctx.op_buf);
715
716                                    if (eRet !=  OMX_ErrorNone) {
717                                        DEBUG_PRINT_ERROR("set_buffer_req failed eRet = %d",eRet);
718                                        pThis->omx_report_error();
719                                        break;
720                                    }
721                                }
722
723                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
724                                        OMX_EventCmdComplete, p1, p2, NULL );
725                                break;
726                            case OMX_CommandPortEnable:
727                                DEBUG_PRINT_HIGH("OMX_CommandPortEnable complete for port [%d]", p2);
728                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
729                                        OMX_EventCmdComplete, p1, p2, NULL );
730                                break;
731
732                            default:
733                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
734                                        OMX_EventCmdComplete, p1, p2, NULL );
735                                break;
736
737                        }
738                    } else {
739                        DEBUG_PRINT_ERROR("\n ERROR: %s()::EventHandler is NULL", __func__);
740                    }
741
742                    break;
743                case OMX_COMPONENT_GENERATE_ETB_ARBITRARY:
744
745                    if (pThis->empty_this_buffer_proxy_arbitrary((OMX_HANDLETYPE)p1,\
746                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
747                        DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy_arbitrary failure");
748                        pThis->omx_report_error ();
749                    }
750
751                    break;
752                case OMX_COMPONENT_GENERATE_ETB:
753
754                    if (pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
755                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
756                        DEBUG_PRINT_ERROR("\n empty_this_buffer_proxy failure");
757                        pThis->omx_report_error ();
758                    }
759
760                    break;
761
762                case OMX_COMPONENT_GENERATE_FTB:
763
764                    if ( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
765                                (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone) {
766                        DEBUG_PRINT_ERROR("\n fill_this_buffer_proxy failure");
767                        pThis->omx_report_error ();
768                    }
769
770                    break;
771
772                case OMX_COMPONENT_GENERATE_COMMAND:
773                    pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
774                            (OMX_U32)p2,(OMX_PTR)NULL);
775                    break;
776
777                case OMX_COMPONENT_GENERATE_EBD:
778
779                    if (p2 != VDEC_S_SUCCESS && p2 != VDEC_S_INPUT_BITSTREAM_ERR) {
780                        DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EBD failure");
781                        pThis->omx_report_error ();
782                    } else {
783                        if (p2 == VDEC_S_INPUT_BITSTREAM_ERR && p1) {
784                            pThis->m_inp_err_count++;
785                            pThis->time_stamp_dts.remove_time_stamp(
786                                    ((OMX_BUFFERHEADERTYPE *)p1)->nTimeStamp,
787                                    (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
788                                    ?true:false);
789                        } else {
790                            pThis->m_inp_err_count = 0;
791                        }
792
793                        if ( pThis->empty_buffer_done(&pThis->m_cmp,
794                                    (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
795                            DEBUG_PRINT_ERROR("\n empty_buffer_done failure");
796                            pThis->omx_report_error ();
797                        }
798
799                        if (!pThis->arbitrary_bytes && pThis->m_inp_err_count > MAX_INPUT_ERROR) {
800                            DEBUG_PRINT_ERROR("\n Input bitstream error for consecutive %d frames.", MAX_INPUT_ERROR);
801                            pThis->omx_report_error ();
802                        }
803                    }
804
805                    break;
806                case OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED:
807                    {
808                        int64_t *timestamp = (int64_t *)p1;
809
810                        if (p1) {
811                            pThis->time_stamp_dts.remove_time_stamp(*timestamp,
812                                    (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
813                                    ?true:false);
814                            free(timestamp);
815                        }
816                    }
817                    break;
818                case OMX_COMPONENT_GENERATE_FBD:
819
820                    if (p2 != VDEC_S_SUCCESS) {
821                        DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_FBD failure");
822                        pThis->omx_report_error ();
823                    } else if ( pThis->fill_buffer_done(&pThis->m_cmp,
824                                (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
825                        DEBUG_PRINT_ERROR("\n fill_buffer_done failure");
826                        pThis->omx_report_error ();
827                    }
828
829                    break;
830
831                case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
832                    DEBUG_PRINT_HIGH("Driver flush i/p Port complete");
833
834                    if (!pThis->input_flush_progress) {
835                        DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
836                    } else {
837                        pThis->execute_input_flush();
838
839                        if (pThis->m_cb.EventHandler) {
840                            if (p2 != VDEC_S_SUCCESS) {
841                                DEBUG_PRINT_ERROR("\nOMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH failure");
842                                pThis->omx_report_error ();
843                            } else {
844                                /*Check if we need generate event for Flush done*/
845                                if (BITMASK_PRESENT(&pThis->m_flags,
846                                            OMX_COMPONENT_INPUT_FLUSH_PENDING)) {
847                                    BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
848                                    DEBUG_PRINT_LOW("Input Flush completed - Notify Client");
849                                    pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
850                                            OMX_EventCmdComplete,OMX_CommandFlush,
851                                            OMX_CORE_INPUT_PORT_INDEX,NULL );
852                                }
853
854                                if (BITMASK_PRESENT(&pThis->m_flags,
855                                            OMX_COMPONENT_IDLE_PENDING)) {
856                                    if (!pThis->output_flush_progress) {
857                                        DEBUG_PRINT_LOW("Output flush done hence issue stop");
858
859                                        if (ioctl (pThis->drv_ctx.video_driver_fd,
860                                                    VDEC_IOCTL_CMD_STOP,NULL ) < 0) {
861                                            DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
862                                            pThis->omx_report_error ();
863                                        }
864                                    }
865                                }
866                            }
867                        } else {
868                            DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
869                        }
870                    }
871
872                    break;
873
874                case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
875                    DEBUG_PRINT_HIGH("Driver flush o/p Port complete");
876
877                    if (!pThis->output_flush_progress) {
878                        DEBUG_PRINT_ERROR("\n WARNING: Unexpected flush from driver");
879                    } else {
880                        pThis->execute_output_flush();
881
882                        if (pThis->m_cb.EventHandler) {
883                            if (p2 != VDEC_S_SUCCESS) {
884                                DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH failed");
885                                pThis->omx_report_error ();
886                            } else {
887                                /*Check if we need generate event for Flush done*/
888                                if (BITMASK_PRESENT(&pThis->m_flags,
889                                            OMX_COMPONENT_OUTPUT_FLUSH_PENDING)) {
890                                    DEBUG_PRINT_LOW("Notify Output Flush done");
891                                    BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
892                                    pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
893                                            OMX_EventCmdComplete,OMX_CommandFlush,
894                                            OMX_CORE_OUTPUT_PORT_INDEX,NULL );
895                                }
896
897                                if (BITMASK_PRESENT(&pThis->m_flags,
898                                            OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING)) {
899                                    DEBUG_PRINT_LOW("Internal flush complete");
900                                    BITMASK_CLEAR (&pThis->m_flags,
901                                            OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
902
903                                    if (BITMASK_PRESENT(&pThis->m_flags,
904                                                OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED)) {
905                                        pThis->post_event(OMX_CommandPortDisable,
906                                                OMX_CORE_OUTPUT_PORT_INDEX,
907                                                OMX_COMPONENT_GENERATE_EVENT);
908                                        BITMASK_CLEAR (&pThis->m_flags,
909                                                OMX_COMPONENT_DISABLE_OUTPUT_DEFERRED);
910
911                                    }
912                                }
913
914                                if (BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING)) {
915                                    if (!pThis->input_flush_progress) {
916                                        DEBUG_PRINT_LOW("Input flush done hence issue stop");
917
918                                        if (ioctl (pThis->drv_ctx.video_driver_fd,
919                                                    VDEC_IOCTL_CMD_STOP,NULL ) < 0) {
920                                            DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_STOP failed");
921                                            pThis->omx_report_error ();
922                                        }
923                                    }
924                                }
925                            }
926                        } else {
927                            DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
928                        }
929                    }
930
931                    break;
932
933                case OMX_COMPONENT_GENERATE_START_DONE:
934                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_START_DONE");
935
936                    if (pThis->m_cb.EventHandler) {
937                        if (p2 != VDEC_S_SUCCESS) {
938                            DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_START_DONE Failure");
939                            pThis->omx_report_error ();
940                        } else {
941                            DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_START_DONE Success");
942
943                            if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
944                                DEBUG_PRINT_LOW("Move to executing");
945                                // Send the callback now
946                                BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
947                                pThis->m_state = OMX_StateExecuting;
948                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
949                                        OMX_EventCmdComplete,OMX_CommandStateSet,
950                                        OMX_StateExecuting, NULL);
951                            } else if (BITMASK_PRESENT(&pThis->m_flags,
952                                        OMX_COMPONENT_PAUSE_PENDING)) {
953                                if (ioctl (pThis->drv_ctx.video_driver_fd,
954                                            VDEC_IOCTL_CMD_PAUSE,NULL ) < 0) {
955                                    DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_PAUSE failed");
956                                    pThis->omx_report_error ();
957                                }
958                            }
959                        }
960                    } else {
961                        DEBUG_PRINT_ERROR("\n Event Handler callback is NULL");
962                    }
963
964                    break;
965
966                case OMX_COMPONENT_GENERATE_PAUSE_DONE:
967                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PAUSE_DONE");
968
969                    if (pThis->m_cb.EventHandler) {
970                        if (p2 != VDEC_S_SUCCESS) {
971                            DEBUG_PRINT_ERROR("OMX_COMPONENT_GENERATE_PAUSE_DONE ret failed");
972                            pThis->omx_report_error ();
973                        } else {
974                            pThis->complete_pending_buffer_done_cbs();
975
976                            if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING)) {
977                                DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_PAUSE_DONE nofity");
978                                //Send the callback now
979                                BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
980                                pThis->m_state = OMX_StatePause;
981                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
982                                        OMX_EventCmdComplete,OMX_CommandStateSet,
983                                        OMX_StatePause, NULL);
984                            }
985                        }
986                    } else {
987                        DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
988                    }
989
990                    break;
991
992                case OMX_COMPONENT_GENERATE_RESUME_DONE:
993                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_RESUME_DONE");
994
995                    if (pThis->m_cb.EventHandler) {
996                        if (p2 != VDEC_S_SUCCESS) {
997                            DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_RESUME_DONE failed");
998                            pThis->omx_report_error ();
999                        } else {
1000                            if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING)) {
1001                                DEBUG_PRINT_LOW("Moving the decoder to execute state");
1002                                // Send the callback now
1003                                BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
1004                                pThis->m_state = OMX_StateExecuting;
1005                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1006                                        OMX_EventCmdComplete,OMX_CommandStateSet,
1007                                        OMX_StateExecuting,NULL);
1008                            }
1009                        }
1010                    } else {
1011                        DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1012                    }
1013
1014                    break;
1015
1016                case OMX_COMPONENT_GENERATE_STOP_DONE:
1017                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_STOP_DONE");
1018
1019                    if (pThis->m_cb.EventHandler) {
1020                        if (p2 != VDEC_S_SUCCESS) {
1021                            DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_STOP_DONE ret failed");
1022                            pThis->omx_report_error ();
1023                        } else {
1024                            pThis->complete_pending_buffer_done_cbs();
1025
1026                            if (BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING)) {
1027                                DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_STOP_DONE Success");
1028                                // Send the callback now
1029                                BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
1030                                pThis->m_state = OMX_StateIdle;
1031                                DEBUG_PRINT_LOW("Move to Idle State");
1032                                pThis->m_cb.EventHandler(&pThis->m_cmp,pThis->m_app_data,
1033                                        OMX_EventCmdComplete,OMX_CommandStateSet,
1034                                        OMX_StateIdle,NULL);
1035                            }
1036                        }
1037                    } else {
1038                        DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1039                    }
1040
1041                    break;
1042
1043                case OMX_COMPONENT_GENERATE_PORT_RECONFIG:
1044                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_PORT_RECONFIG");
1045
1046                    if (pThis->start_port_reconfig() != OMX_ErrorNone)
1047                        pThis->omx_report_error();
1048                    else {
1049                        if (pThis->in_reconfig) {
1050                            if (pThis->m_cb.EventHandler) {
1051                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1052                                        OMX_EventPortSettingsChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1053                            } else {
1054                                DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1055                            }
1056                        }
1057
1058                        if (pThis->drv_ctx.interlace != VDEC_InterlaceFrameProgressive) {
1059                            OMX_INTERLACETYPE format = (OMX_INTERLACETYPE)-1;
1060                            OMX_EVENTTYPE event = (OMX_EVENTTYPE)OMX_EventIndexsettingChanged;
1061
1062                            if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
1063                                format = OMX_InterlaceInterleaveFrameTopFieldFirst;
1064                            else if (pThis->drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
1065                                format = OMX_InterlaceInterleaveFrameBottomFieldFirst;
1066                            else //unsupported interlace format; raise a error
1067                                event = OMX_EventError;
1068
1069                            if (pThis->m_cb.EventHandler) {
1070                                pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1071                                        event, format, 0, NULL );
1072                            } else {
1073                                DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1074                            }
1075                        }
1076                    }
1077
1078                    break;
1079
1080                case OMX_COMPONENT_GENERATE_EOS_DONE:
1081                    DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_EOS_DONE");
1082
1083                    if (pThis->m_cb.EventHandler) {
1084                        pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data, OMX_EventBufferFlag,
1085                                OMX_CORE_OUTPUT_PORT_INDEX, OMX_BUFFERFLAG_EOS, NULL );
1086                    } else {
1087                        DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1088                    }
1089
1090                    pThis->prev_ts = LLONG_MAX;
1091                    pThis->rst_prev_ts = true;
1092                    break;
1093
1094                case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
1095                    DEBUG_PRINT_ERROR("\n OMX_COMPONENT_GENERATE_HARDWARE_ERROR");
1096                    pThis->omx_report_error ();
1097                    break;
1098                case OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG:
1099                    {
1100                        DEBUG_PRINT_HIGH("Rxd OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG");
1101
1102                        if (pThis->m_cb.EventHandler) {
1103                            pThis->m_cb.EventHandler(&pThis->m_cmp, pThis->m_app_data,
1104                                    (OMX_EVENTTYPE)OMX_EventIndexsettingChanged, OMX_CORE_OUTPUT_PORT_INDEX, 0, NULL );
1105                        } else {
1106                            DEBUG_PRINT_ERROR("ERROR: %s()::EventHandler is NULL", __func__);
1107                        }
1108
1109                        //update power HAL with new width, height and bitrate
1110                        pThis->power_module_deregister();
1111                        pThis->power_module_register();
1112                    }
1113                default:
1114                    break;
1115            }
1116        }
1117
1118        pthread_mutex_lock(&pThis->m_lock);
1119        qsize = pThis->m_cmd_q.m_size;
1120
1121        if (pThis->m_state != OMX_StatePause)
1122            qsize += (pThis->m_ftb_q.m_size + pThis->m_etb_q.m_size);
1123
1124        pthread_mutex_unlock(&pThis->m_lock);
1125    } while (qsize>0);
1126
1127}
1128
1129
1130
1131/* ======================================================================
1132   FUNCTION
1133   omx_vdec::ComponentInit
1134
1135   DESCRIPTION
1136   Initialize the component.
1137
1138   PARAMETERS
1139   ctxt -- Context information related to the self.
1140   id   -- Event identifier. This could be any of the following:
1141   1. Command completion event
1142   2. Buffer done callback event
1143   3. Frame done callback event
1144
1145   RETURN VALUE
1146   None.
1147
1148   ========================================================================== */
1149OMX_ERRORTYPE omx_vdec::component_init(OMX_STRING role)
1150{
1151
1152    OMX_ERRORTYPE eRet = OMX_ErrorNone;
1153    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
1154    unsigned int   alignment = 0,buffer_size = 0;
1155    int is_secure = 0;
1156    int i = 0;
1157    int fds[2];
1158    int r;
1159    OMX_STRING device_name = "/dev/msm_vidc_dec";
1160
1161#ifndef JB_MR1
1162    sp<IServiceManager> sm;
1163    sp<hwcService::IHWComposer> hwcBinder = NULL;
1164#endif
1165
1166    if (!strncmp(role, "OMX.qcom.video.decoder.avc.secure",OMX_MAX_STRINGNAME_SIZE)) {
1167        secure_mode = true;
1168        arbitrary_bytes = false;
1169        role = "OMX.qcom.video.decoder.avc";
1170        device_name =  "/dev/msm_vidc_dec_sec";
1171        is_secure = 1;
1172    } else if (!strncmp(role, "OMX.qcom.video.decoder.mpeg2.secure",OMX_MAX_STRINGNAME_SIZE)) {
1173        secure_mode = true;
1174        arbitrary_bytes = false;
1175        role = "OMX.qcom.video.decoder.mpeg2";
1176        device_name =  "/dev/msm_vidc_dec_sec";
1177        is_secure = 1;
1178    }
1179
1180#ifndef JB_MR1
1181
1182    if (secure_mode) {
1183        sm = defaultServiceManager();
1184        hwcBinder =
1185            interface_cast<hwcService::IHWComposer>(sm->getService(String16("display.hwcservice")));
1186
1187        if (hwcBinder != NULL) {
1188            hwcBinder->setOpenSecureStart();
1189        } else {
1190            DEBUG_PRINT_HIGH("Failed to get ref to hwcBinder, "
1191                    "cannot call secure display start");
1192        }
1193    }
1194
1195#endif
1196    DEBUG_PRINT_HIGH("omx_vdec::component_init(): Start of New Playback : role  = %s : DEVICE = %s",
1197            role, device_name);
1198
1199    drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK);
1200
1201    DEBUG_PRINT_HIGH("omx_vdec::component_init(): Open returned fd %d, errno %d",
1202            drv_ctx.video_driver_fd, errno);
1203
1204    if (drv_ctx.video_driver_fd == 0) {
1205        drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK);
1206    }
1207
1208    if (is_secure && drv_ctx.video_driver_fd < 0) {
1209        do {
1210            usleep(100 * 1000);
1211            drv_ctx.video_driver_fd = open(device_name, O_RDWR | O_NONBLOCK);
1212
1213            if (drv_ctx.video_driver_fd > 0) {
1214                break;
1215            }
1216        } while (i++ < 50);
1217    }
1218
1219    if (drv_ctx.video_driver_fd < 0) {
1220        DEBUG_PRINT_ERROR("\n Omx_vdec::Comp Init Returning failure, errno %d", errno);
1221        return OMX_ErrorInsufficientResources;
1222    }
1223
1224    drv_ctx.frame_rate.fps_numerator = DEFAULT_FPS;
1225    drv_ctx.frame_rate.fps_denominator = 1;
1226
1227
1228#ifdef INPUT_BUFFER_LOG
1229    strcpy(inputfilename, INPUT_BUFFER_FILE_NAME);
1230#endif
1231#ifdef OUTPUT_BUFFER_LOG
1232    outputBufferFile1 = fopen (outputfilename, "ab");
1233#endif
1234#ifdef OUTPUT_EXTRADATA_LOG
1235    outputExtradataFile = fopen (ouputextradatafilename, "ab");
1236#endif
1237
1238    // Copy the role information which provides the decoder kind
1239    strlcpy(drv_ctx.kind,role,128);
1240
1241    if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg4",\
1242                OMX_MAX_STRINGNAME_SIZE)) {
1243        strlcpy((char *)m_cRole, "video_decoder.mpeg4",\
1244                OMX_MAX_STRINGNAME_SIZE);
1245        drv_ctx.timestamp_adjust = true;
1246        drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG4;
1247        eCompressionFormat = OMX_VIDEO_CodingMPEG4;
1248        /*Initialize Start Code for MPEG4*/
1249        codec_type_parse = CODEC_TYPE_MPEG4;
1250        m_frame_parser.init_start_codes (codec_type_parse);
1251#ifdef INPUT_BUFFER_LOG
1252        strcat(inputfilename, "m4v");
1253#endif
1254    } else if (!strncmp(drv_ctx.kind,"OMX.qcom.video.decoder.mpeg2",\
1255                OMX_MAX_STRINGNAME_SIZE)) {
1256        strlcpy((char *)m_cRole, "video_decoder.mpeg2",\
1257                OMX_MAX_STRINGNAME_SIZE);
1258        drv_ctx.decoder_format = VDEC_CODECTYPE_MPEG2;
1259        eCompressionFormat = OMX_VIDEO_CodingMPEG2;
1260        /*Initialize Start Code for MPEG2*/
1261        codec_type_parse = CODEC_TYPE_MPEG2;
1262        m_frame_parser.init_start_codes (codec_type_parse);
1263#ifdef INPUT_BUFFER_LOG
1264        strcat(inputfilename, "mpg");
1265#endif
1266    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",\
1267                OMX_MAX_STRINGNAME_SIZE)) {
1268        strlcpy((char *)m_cRole, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
1269        DEBUG_PRINT_LOW("H263 Decoder selected");
1270        drv_ctx.decoder_format = VDEC_CODECTYPE_H263;
1271        eCompressionFormat = OMX_VIDEO_CodingH263;
1272        codec_type_parse = CODEC_TYPE_H263;
1273        m_frame_parser.init_start_codes (codec_type_parse);
1274#ifdef INPUT_BUFFER_LOG
1275        strcat(inputfilename, "263");
1276#endif
1277    }
1278
1279#ifdef MAX_RES_1080P
1280    else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",\
1281                OMX_MAX_STRINGNAME_SIZE)) {
1282        strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1283        DEBUG_PRINT_LOW ("DIVX 311 Decoder selected");
1284        drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_3;
1285        eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1286        codec_type_parse = CODEC_TYPE_DIVX;
1287        m_frame_parser.init_start_codes (codec_type_parse);
1288#ifdef _ANDROID_
1289        OMX_ERRORTYPE err = createDivxDrmContext();
1290
1291        if ( err != OMX_ErrorNone ) {
1292            DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1293            eRet = err;
1294            goto cleanup;
1295        }
1296
1297#endif //_ANDROID_
1298    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1299                OMX_MAX_STRINGNAME_SIZE)) {
1300        strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1301        DEBUG_PRINT_ERROR ("DIVX 4 Decoder selected");
1302        drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_4;
1303        eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1304        codec_type_parse = CODEC_TYPE_DIVX;
1305        m_frame_parser.init_start_codes (codec_type_parse);
1306#ifdef _ANDROID_
1307        OMX_ERRORTYPE err = createDivxDrmContext();
1308
1309        if ( err != OMX_ErrorNone ) {
1310            DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1311            eRet = err;
1312            goto cleanup;
1313        }
1314
1315#endif //_ANDROID_
1316    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",\
1317                OMX_MAX_STRINGNAME_SIZE)) {
1318        strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1319        DEBUG_PRINT_ERROR ("DIVX 5/6 Decoder selected");
1320        drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_6;
1321        eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1322        codec_type_parse = CODEC_TYPE_DIVX;
1323        m_frame_parser.init_start_codes (codec_type_parse);
1324#ifdef _ANDROID_
1325        OMX_ERRORTYPE err = createDivxDrmContext();
1326
1327        if ( err != OMX_ErrorNone ) {
1328            DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1329            eRet = err;
1330            goto cleanup;
1331        }
1332
1333#endif //_ANDROID_
1334    }
1335
1336#else
1337    else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx4",\
1338                    OMX_MAX_STRINGNAME_SIZE)) || (!strncmp(drv_ctx.kind, \
1339                        "OMX.qcom.video.decoder.divx", OMX_MAX_STRINGNAME_SIZE))) {
1340        strlcpy((char *)m_cRole, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
1341        DEBUG_PRINT_ERROR ("DIVX Decoder selected");
1342        drv_ctx.decoder_format = VDEC_CODECTYPE_DIVX_5;
1343        eCompressionFormat = (OMX_VIDEO_CODINGTYPE)QOMX_VIDEO_CodingDivx;
1344        codec_type_parse = CODEC_TYPE_DIVX;
1345        m_frame_parser.init_start_codes (codec_type_parse);
1346
1347#ifdef _ANDROID_
1348        OMX_ERRORTYPE err = createDivxDrmContext();
1349
1350        if ( err != OMX_ErrorNone ) {
1351            DEBUG_PRINT_ERROR("createDivxDrmContext Failed");
1352            eRet = err;
1353            goto cleanup;
1354        }
1355
1356#endif //_ANDROID_
1357    }
1358
1359#endif
1360    else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",\
1361                OMX_MAX_STRINGNAME_SIZE)) {
1362        strlcpy((char *)m_cRole, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
1363        drv_ctx.decoder_format = VDEC_CODECTYPE_H264;
1364        eCompressionFormat = OMX_VIDEO_CodingAVC;
1365        codec_type_parse = CODEC_TYPE_H264;
1366        m_frame_parser.init_start_codes (codec_type_parse);
1367        m_frame_parser.init_nal_length(nal_length);
1368#ifdef INPUT_BUFFER_LOG
1369        strcat(inputfilename, "264");
1370#endif
1371    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",\
1372                OMX_MAX_STRINGNAME_SIZE)) {
1373        strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1374        drv_ctx.decoder_format = VDEC_CODECTYPE_VC1;
1375        eCompressionFormat = OMX_VIDEO_CodingWMV;
1376        codec_type_parse = CODEC_TYPE_VC1;
1377        m_frame_parser.init_start_codes (codec_type_parse);
1378#ifdef INPUT_BUFFER_LOG
1379        strcat(inputfilename, "vc1");
1380#endif
1381    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",\
1382                OMX_MAX_STRINGNAME_SIZE)) {
1383        strlcpy((char *)m_cRole, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
1384        drv_ctx.decoder_format = VDEC_CODECTYPE_VC1_RCV;
1385        eCompressionFormat = OMX_VIDEO_CodingWMV;
1386        codec_type_parse = CODEC_TYPE_VC1;
1387        m_frame_parser.init_start_codes (codec_type_parse);
1388#ifdef INPUT_BUFFER_LOG
1389        strcat(inputfilename, "vc1");
1390#endif
1391    } else {
1392        DEBUG_PRINT_ERROR("\nERROR:Unknown Component\n");
1393        eRet = OMX_ErrorInvalidComponentName;
1394    }
1395
1396#ifdef INPUT_BUFFER_LOG
1397    inputBufferFile1 = fopen (inputfilename, "ab");
1398#endif
1399
1400    if (eRet == OMX_ErrorNone) {
1401#ifdef MAX_RES_720P
1402        drv_ctx.output_format = VDEC_YUV_FORMAT_NV12;
1403
1404#endif
1405#ifdef MAX_RES_1080P
1406        drv_ctx.output_format = VDEC_YUV_FORMAT_TILE_4x2;
1407        OMX_COLOR_FORMATTYPE dest_color_format = (OMX_COLOR_FORMATTYPE)
1408            QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
1409
1410        if (!client_buffers.set_color_format(dest_color_format)) {
1411            DEBUG_PRINT_ERROR("\n Setting color format failed");
1412            eRet = OMX_ErrorInsufficientResources;
1413        }
1414
1415#endif
1416        /*Initialize Decoder with codec type and resolution*/
1417        ioctl_msg.in = &drv_ctx.decoder_format;
1418        ioctl_msg.out = NULL;
1419
1420        if ( (eRet == OMX_ErrorNone) &&
1421                ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_CODEC,
1422                    (void*)&ioctl_msg) < 0)
1423
1424        {
1425            DEBUG_PRINT_ERROR("\n Set codec type failed");
1426            eRet = OMX_ErrorInsufficientResources;
1427        }
1428
1429        /*Set the output format*/
1430        ioctl_msg.in = &drv_ctx.output_format;
1431        ioctl_msg.out = NULL;
1432
1433        if ( (eRet == OMX_ErrorNone) &&
1434                ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_OUTPUT_FORMAT,
1435                    (void*)&ioctl_msg) < 0) {
1436            DEBUG_PRINT_ERROR("\n Set output format failed");
1437            eRet = OMX_ErrorInsufficientResources;
1438        }
1439
1440#ifdef MAX_RES_720P
1441        drv_ctx.video_resolution.frame_height =
1442            drv_ctx.video_resolution.scan_lines = 720;
1443        drv_ctx.video_resolution.frame_width =
1444            drv_ctx.video_resolution.stride = 1280;
1445#endif
1446#ifdef MAX_RES_1080P
1447        drv_ctx.video_resolution.frame_height =
1448            drv_ctx.video_resolution.scan_lines = 1088;
1449        drv_ctx.video_resolution.frame_width =
1450            drv_ctx.video_resolution.stride = 1920;
1451#endif
1452
1453        ioctl_msg.in = &drv_ctx.video_resolution;
1454        ioctl_msg.out = NULL;
1455
1456        if ( (eRet == OMX_ErrorNone) &&
1457                ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_PICRES,
1458                    (void*)&ioctl_msg) < 0) {
1459            DEBUG_PRINT_ERROR("\n Set Resolution failed");
1460            eRet = OMX_ErrorInsufficientResources;
1461        }
1462
1463        /*Get the Buffer requirements for input and output ports*/
1464        drv_ctx.ip_buf.buffer_type = VDEC_BUFFER_TYPE_INPUT;
1465        drv_ctx.op_buf.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
1466        drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
1467        drv_ctx.extradata = 0;
1468        drv_ctx.picture_order = VDEC_ORDER_DISPLAY;
1469        drv_ctx.idr_only_decoding = 0;
1470
1471        if (eRet == OMX_ErrorNone)
1472            eRet = get_buffer_req(&drv_ctx.ip_buf);
1473
1474        if (eRet == OMX_ErrorNone)
1475            eRet = get_buffer_req(&drv_ctx.op_buf);
1476
1477        m_state = OMX_StateLoaded;
1478#ifdef DEFAULT_EXTRADATA
1479
1480        if (eRet == OMX_ErrorNone)
1481            eRet = enable_extradata(DEFAULT_EXTRADATA);
1482
1483#endif
1484
1485        if ( (codec_type_parse == CODEC_TYPE_VC1) ||
1486                (codec_type_parse == CODEC_TYPE_H264)) { //add CP check here
1487            //Check if dmx can be disabled
1488            struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
1489            OMX_ERRORTYPE eRet = OMX_ErrorNone;
1490            ioctl_msg.out = &drv_ctx.disable_dmx;
1491
1492            if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT, &ioctl_msg)) {
1493                DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_DISABLE_DMX_SUPPORT");
1494                eRet = OMX_ErrorHardware;
1495            } else {
1496                if (drv_ctx.disable_dmx && !secure_mode) {
1497                    DEBUG_PRINT_HIGH("DMX disable is supported");
1498
1499                    int rc = ioctl(drv_ctx.video_driver_fd,
1500                            VDEC_IOCTL_SET_DISABLE_DMX);
1501
1502                    if (rc < 0) {
1503                        DEBUG_PRINT_ERROR("Failed to disable dmx on driver.");
1504                        drv_ctx.disable_dmx = false;
1505                        eRet = OMX_ErrorHardware;
1506                    }
1507                } else {
1508                    drv_ctx.disable_dmx = false;
1509                }
1510            }
1511        }
1512
1513        if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
1514            if (m_frame_parser.mutils == NULL) {
1515                m_frame_parser.mutils = new H264_Utils();
1516
1517                if (m_frame_parser.mutils == NULL) {
1518                    DEBUG_PRINT_ERROR("\n parser utils Allocation failed ");
1519                    eRet = OMX_ErrorInsufficientResources;
1520                } else {
1521                    h264_scratch.nAllocLen = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH;
1522                    h264_scratch.pBuffer = (OMX_U8 *)malloc (h264_scratch.nAllocLen);
1523                    h264_scratch.nFilledLen = 0;
1524                    h264_scratch.nOffset = 0;
1525
1526                    if (h264_scratch.pBuffer == NULL) {
1527                        DEBUG_PRINT_ERROR("\n h264_scratch.pBuffer Allocation failed ");
1528                        return OMX_ErrorInsufficientResources;
1529                    }
1530
1531                    m_frame_parser.mutils->initialize_frame_checking_environment();
1532                    m_frame_parser.mutils->allocate_rbsp_buffer (drv_ctx.ip_buf.buffer_size);
1533                }
1534            }
1535
1536            h264_parser = new h264_stream_parser();
1537
1538            if (!h264_parser) {
1539                DEBUG_PRINT_ERROR("ERROR: H264 parser allocation failed!");
1540                eRet = OMX_ErrorInsufficientResources;
1541            }
1542        }
1543
1544        if (pipe(fds)) {
1545            DEBUG_PRINT_ERROR("\n pipe creation failed.");
1546            eRet = OMX_ErrorInsufficientResources;
1547        } else {
1548            int temp1[2];
1549
1550            if (fds[0] == 0 || fds[1] == 0) {
1551                if (pipe (temp1)) {
1552                    DEBUG_PRINT_ERROR("\n pipe creation failed..");
1553                    return OMX_ErrorInsufficientResources;
1554                }
1555
1556                //close (fds[0]);
1557                //close (fds[1]);
1558                fds[0] = temp1 [0];
1559                fds[1] = temp1 [1];
1560            }
1561
1562            m_pipe_in = fds[0];
1563            m_pipe_out = fds[1];
1564            r = pthread_create(&msg_thread_id,0,message_thread,this);
1565
1566            if (r < 0) {
1567                DEBUG_PRINT_ERROR("\n component_init(): message_thread creation failed");
1568                eRet = OMX_ErrorInsufficientResources;
1569            } else {
1570                msg_thread_created = true;
1571                r = pthread_create(&async_thread_id,0,async_message_thread,this);
1572
1573                if (r < 0) {
1574                    DEBUG_PRINT_ERROR("\n component_init(): async_message_thread creation failed");
1575                    eRet = OMX_ErrorInsufficientResources;
1576                } else {
1577                    async_thread_created = true;
1578                }
1579            }
1580        }
1581    }
1582
1583    if (eRet != OMX_ErrorNone) {
1584        DEBUG_PRINT_ERROR("\n Component Init Failed");
1585        DEBUG_PRINT_HIGH("Calling VDEC_IOCTL_STOP_NEXT_MSG");
1586        (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
1587                NULL);
1588    } else {
1589        DEBUG_PRINT_HIGH("omx_vdec::component_init() success");
1590    }
1591
1592    memset(&h264_mv_buff,0,sizeof(struct h264_mv_buffer));
1593    memset(&meta_buff,0,sizeof(struct meta_buffer));
1594cleanup:
1595
1596    if (!secure_mode) {
1597        return eRet;
1598    }
1599
1600#ifndef JB_MR1
1601
1602    if (hwcBinder != NULL) {
1603        (eRet == OMX_ErrorNone) ?
1604            hwcBinder->setOpenSecureEnd() :
1605            hwcBinder->setCloseSecureEnd();
1606    } else {
1607        DEBUG_PRINT_HIGH("hwcBinder not found, "
1608                "not calling secure end");
1609    }
1610
1611#endif
1612    return eRet;
1613}
1614
1615/* ======================================================================
1616   FUNCTION
1617   omx_vdec::GetComponentVersion
1618
1619   DESCRIPTION
1620   Returns the component version.
1621
1622   PARAMETERS
1623   TBD.
1624
1625   RETURN VALUE
1626   OMX_ErrorNone.
1627
1628   ========================================================================== */
1629OMX_ERRORTYPE  omx_vdec::get_component_version
1630(
1631 OMX_IN OMX_HANDLETYPE hComp,
1632 OMX_OUT OMX_STRING componentName,
1633 OMX_OUT OMX_VERSIONTYPE* componentVersion,
1634 OMX_OUT OMX_VERSIONTYPE* specVersion,
1635 OMX_OUT OMX_UUIDTYPE* componentUUID
1636 )
1637{
1638    if (m_state == OMX_StateInvalid) {
1639        DEBUG_PRINT_ERROR("\n Get Comp Version in Invalid State");
1640        return OMX_ErrorInvalidState;
1641    }
1642
1643    /* TBD -- Return the proper version */
1644    if (specVersion) {
1645        specVersion->nVersion = OMX_SPEC_VERSION;
1646    }
1647
1648    return OMX_ErrorNone;
1649}
1650/* ======================================================================
1651   FUNCTION
1652   omx_vdec::SendCommand
1653
1654   DESCRIPTION
1655   Returns zero if all the buffers released..
1656
1657   PARAMETERS
1658   None.
1659
1660   RETURN VALUE
1661   true/false
1662
1663   ========================================================================== */
1664OMX_ERRORTYPE  omx_vdec::send_command(OMX_IN OMX_HANDLETYPE hComp,
1665        OMX_IN OMX_COMMANDTYPE cmd,
1666        OMX_IN OMX_U32 param1,
1667        OMX_IN OMX_PTR cmdData
1668        )
1669{
1670    DEBUG_PRINT_HIGH("send_command: Recieved a Command from Client");
1671
1672    if (m_state == OMX_StateInvalid) {
1673        DEBUG_PRINT_ERROR("\n ERROR: Send Command in Invalid State");
1674        return OMX_ErrorInvalidState;
1675    }
1676
1677    if (cmd == OMX_CommandFlush && param1 != OMX_CORE_INPUT_PORT_INDEX
1678            && param1 != OMX_CORE_OUTPUT_PORT_INDEX && param1 != OMX_ALL) {
1679        DEBUG_PRINT_ERROR("\n send_command(): ERROR OMX_CommandFlush "
1680                "to invalid port: %d", param1);
1681        return OMX_ErrorBadPortIndex;
1682    }
1683
1684    post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
1685    sem_wait(&m_cmd_lock);
1686    DEBUG_PRINT_HIGH("send_command: Command Processed");
1687    return OMX_ErrorNone;
1688}
1689
1690/* ======================================================================
1691   FUNCTION
1692   omx_vdec::SendCommand
1693
1694   DESCRIPTION
1695   Returns zero if all the buffers released..
1696
1697   PARAMETERS
1698   None.
1699
1700   RETURN VALUE
1701   true/false
1702
1703   ========================================================================== */
1704OMX_ERRORTYPE  omx_vdec::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
1705        OMX_IN OMX_COMMANDTYPE cmd,
1706        OMX_IN OMX_U32 param1,
1707        OMX_IN OMX_PTR cmdData
1708        )
1709{
1710    OMX_ERRORTYPE eRet = OMX_ErrorNone;
1711    OMX_STATETYPE eState = (OMX_STATETYPE) param1;
1712    int bFlag = 1,sem_posted = 0;
1713
1714    DEBUG_PRINT_HIGH("send_command_proxy(): cmd = %d, Current State %d, Expected State %d",
1715            cmd, m_state, eState);
1716
1717    if (cmd == OMX_CommandStateSet) {
1718        DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandStateSet issued");
1719        DEBUG_PRINT_HIGH("Current State %d, Expected State %d", m_state, eState);
1720
1721        /***************************/
1722
1723        /* Current State is Loaded */
1724
1725        /***************************/
1726        if (m_state == OMX_StateLoaded) {
1727            if (eState == OMX_StateIdle) {
1728                //if all buffers are allocated or all ports disabled
1729                if (allocate_done() ||
1730                        (m_inp_bEnabled == OMX_FALSE && m_out_bEnabled == OMX_FALSE)) {
1731                    DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle");
1732                } else {
1733                    DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->Idle-Pending");
1734                    BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
1735                    // Skip the event notification
1736                    bFlag = 0;
1737                }
1738            }
1739            /* Requesting transition from Loaded to Loaded */
1740            else if (eState == OMX_StateLoaded) {
1741                DEBUG_PRINT_ERROR("\n ERROR::send_command_proxy(): Loaded-->Loaded");
1742                post_event(OMX_EventError,OMX_ErrorSameState,\
1743                        OMX_COMPONENT_GENERATE_EVENT);
1744                eRet = OMX_ErrorSameState;
1745            }
1746            /* Requesting transition from Loaded to WaitForResources */
1747            else if (eState == OMX_StateWaitForResources) {
1748                /* Since error is None , we will post an event
1749                   at the end of this function definition */
1750                DEBUG_PRINT_LOW("send_command_proxy(): Loaded-->WaitForResources");
1751            }
1752            /* Requesting transition from Loaded to Executing */
1753            else if (eState == OMX_StateExecuting) {
1754                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Executing\n");
1755                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1756                        OMX_COMPONENT_GENERATE_EVENT);
1757                eRet = OMX_ErrorIncorrectStateTransition;
1758            }
1759            /* Requesting transition from Loaded to Pause */
1760            else if (eState == OMX_StatePause) {
1761                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Pause\n");
1762                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1763                        OMX_COMPONENT_GENERATE_EVENT);
1764                eRet = OMX_ErrorIncorrectStateTransition;
1765            }
1766            /* Requesting transition from Loaded to Invalid */
1767            else if (eState == OMX_StateInvalid) {
1768                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid\n");
1769                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1770                eRet = OMX_ErrorInvalidState;
1771            } else {
1772                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Loaded-->Invalid(%d Not Handled)\n",\
1773                        eState);
1774                eRet = OMX_ErrorBadParameter;
1775            }
1776        }
1777
1778        /***************************/
1779        /* Current State is IDLE */
1780        /***************************/
1781        else if (m_state == OMX_StateIdle) {
1782            if (eState == OMX_StateLoaded) {
1783                if (release_done()) {
1784                    /*
1785                       Since error is None , we will post an event at the end
1786                       of this function definition
1787                     */
1788                    DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded");
1789                } else {
1790                    DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Loaded-Pending");
1791                    BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
1792                    // Skip the event notification
1793                    bFlag = 0;
1794                }
1795            }
1796            /* Requesting transition from Idle to Executing */
1797            else if (eState == OMX_StateExecuting) {
1798                DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing");
1799                BITMASK_SET(&m_flags, OMX_COMPONENT_EXECUTE_PENDING);
1800                bFlag = 0;
1801
1802                if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1803                            NULL) < 0) {
1804                    DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1805                    omx_report_error ();
1806                    eRet = OMX_ErrorHardware;
1807                } else {
1808                    power_module_register();
1809                }
1810            }
1811            /* Requesting transition from Idle to Idle */
1812            else if (eState == OMX_StateIdle) {
1813                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Idle\n");
1814                post_event(OMX_EventError,OMX_ErrorSameState,\
1815                        OMX_COMPONENT_GENERATE_EVENT);
1816                eRet = OMX_ErrorSameState;
1817            }
1818            /* Requesting transition from Idle to WaitForResources */
1819            else if (eState == OMX_StateWaitForResources) {
1820                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->WaitForResources\n");
1821                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1822                        OMX_COMPONENT_GENERATE_EVENT);
1823                eRet = OMX_ErrorIncorrectStateTransition;
1824            }
1825            /* Requesting transition from Idle to Pause */
1826            else if (eState == OMX_StatePause) {
1827                /*To pause the Video core we need to start the driver*/
1828                if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_START,
1829                            NULL) < 0) {
1830                    DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_START FAILED");
1831                    omx_report_error ();
1832                    eRet = OMX_ErrorHardware;
1833                } else {
1834                    BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1835                    DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Pause");
1836                    bFlag = 0;
1837                }
1838            }
1839            /* Requesting transition from Idle to Invalid */
1840            else if (eState == OMX_StateInvalid) {
1841                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle-->Invalid\n");
1842                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1843                eRet = OMX_ErrorInvalidState;
1844            } else {
1845                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Idle --> %d Not Handled\n",eState);
1846                eRet = OMX_ErrorBadParameter;
1847            }
1848        }
1849
1850        /******************************/
1851        /* Current State is Executing */
1852        /******************************/
1853        else if (m_state == OMX_StateExecuting) {
1854            DEBUG_PRINT_HIGH("Command Recieved in OMX_StateExecuting");
1855
1856            /* Requesting transition from Executing to Idle */
1857            if (eState == OMX_StateIdle) {
1858                /* Since error is None , we will post an event
1859                   at the end of this function definition
1860                 */
1861                DEBUG_PRINT_HIGH("send_command_proxy(): Executing --> Idle");
1862                BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1863
1864                if (!sem_posted) {
1865                    sem_posted = 1;
1866                    sem_post (&m_cmd_lock);
1867                    execute_omx_flush(OMX_ALL);
1868                }
1869
1870                bFlag = 0;
1871            }
1872            /* Requesting transition from Executing to Paused */
1873            else if (eState == OMX_StatePause) {
1874                DEBUG_PRINT_HIGH("PAUSE Command Issued");
1875
1876                if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_PAUSE,
1877                            NULL) < 0) {
1878                    DEBUG_PRINT_ERROR("\n Error In Pause State");
1879                    post_event(OMX_EventError,OMX_ErrorHardware,\
1880                            OMX_COMPONENT_GENERATE_EVENT);
1881                    eRet = OMX_ErrorHardware;
1882                } else {
1883                    BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
1884                    DEBUG_PRINT_HIGH("send_command_proxy(): Executing-->Pause");
1885                    bFlag = 0;
1886                }
1887            }
1888            /* Requesting transition from Executing to Loaded */
1889            else if (eState == OMX_StateLoaded) {
1890                DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Loaded \n");
1891                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1892                        OMX_COMPONENT_GENERATE_EVENT);
1893                eRet = OMX_ErrorIncorrectStateTransition;
1894            }
1895            /* Requesting transition from Executing to WaitForResources */
1896            else if (eState == OMX_StateWaitForResources) {
1897                DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> WaitForResources \n");
1898                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1899                        OMX_COMPONENT_GENERATE_EVENT);
1900                eRet = OMX_ErrorIncorrectStateTransition;
1901            }
1902            /* Requesting transition from Executing to Executing */
1903            else if (eState == OMX_StateExecuting) {
1904                DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Executing \n");
1905                post_event(OMX_EventError,OMX_ErrorSameState,\
1906                        OMX_COMPONENT_GENERATE_EVENT);
1907                eRet = OMX_ErrorSameState;
1908            }
1909            /* Requesting transition from Executing to Invalid */
1910            else if (eState == OMX_StateInvalid) {
1911                DEBUG_PRINT_ERROR("\n send_command_proxy(): Executing --> Invalid \n");
1912                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1913                eRet = OMX_ErrorInvalidState;
1914            } else {
1915                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Executing --> %d Not Handled\n",eState);
1916                eRet = OMX_ErrorBadParameter;
1917            }
1918        }
1919        /***************************/
1920        /* Current State is Pause  */
1921        /***************************/
1922        else if (m_state == OMX_StatePause) {
1923            /* Requesting transition from Pause to Executing */
1924            if (eState == OMX_StateExecuting) {
1925                DEBUG_PRINT_HIGH("Pause --> Executing");
1926
1927                if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_CMD_RESUME,
1928                            NULL) < 0) {
1929                    DEBUG_PRINT_ERROR("\n VDEC_IOCTL_CMD_RESUME failed");
1930                    post_event(OMX_EventError,OMX_ErrorHardware,\
1931                            OMX_COMPONENT_GENERATE_EVENT);
1932                    eRet = OMX_ErrorHardware;
1933                } else {
1934                    BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1935                    DEBUG_PRINT_HIGH("send_command_proxy(): Idle-->Executing");
1936                    post_event (NULL,VDEC_S_SUCCESS,\
1937                            OMX_COMPONENT_GENERATE_RESUME_DONE);
1938                    bFlag = 0;
1939                }
1940            }
1941            /* Requesting transition from Pause to Idle */
1942            else if (eState == OMX_StateIdle) {
1943                /* Since error is None , we will post an event
1944                   at the end of this function definition */
1945                DEBUG_PRINT_HIGH("Pause --> Idle..");
1946                BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1947
1948                if (!sem_posted) {
1949                    sem_posted = 1;
1950                    sem_post (&m_cmd_lock);
1951                    execute_omx_flush(OMX_ALL);
1952                }
1953
1954                bFlag = 0;
1955            }
1956            /* Requesting transition from Pause to loaded */
1957            else if (eState == OMX_StateLoaded) {
1958                DEBUG_PRINT_ERROR("\n Pause --> loaded \n");
1959                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1960                        OMX_COMPONENT_GENERATE_EVENT);
1961                eRet = OMX_ErrorIncorrectStateTransition;
1962            }
1963            /* Requesting transition from Pause to WaitForResources */
1964            else if (eState == OMX_StateWaitForResources) {
1965                DEBUG_PRINT_ERROR("\n Pause --> WaitForResources \n");
1966                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1967                        OMX_COMPONENT_GENERATE_EVENT);
1968                eRet = OMX_ErrorIncorrectStateTransition;
1969            }
1970            /* Requesting transition from Pause to Pause */
1971            else if (eState == OMX_StatePause) {
1972                DEBUG_PRINT_ERROR("\n Pause --> Pause \n");
1973                post_event(OMX_EventError,OMX_ErrorSameState,\
1974                        OMX_COMPONENT_GENERATE_EVENT);
1975                eRet = OMX_ErrorSameState;
1976            }
1977            /* Requesting transition from Pause to Invalid */
1978            else if (eState == OMX_StateInvalid) {
1979                DEBUG_PRINT_ERROR("\n Pause --> Invalid \n");
1980                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1981                eRet = OMX_ErrorInvalidState;
1982            } else {
1983                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Paused --> %d Not Handled\n",eState);
1984                eRet = OMX_ErrorBadParameter;
1985            }
1986        }
1987        /***************************/
1988        /* Current State is WaitForResources  */
1989        /***************************/
1990        else if (m_state == OMX_StateWaitForResources) {
1991            /* Requesting transition from WaitForResources to Loaded */
1992            if (eState == OMX_StateLoaded) {
1993                /* Since error is None , we will post an event
1994                   at the end of this function definition */
1995                DEBUG_PRINT_HIGH("send_command_proxy(): WaitForResources-->Loaded");
1996            }
1997            /* Requesting transition from WaitForResources to WaitForResources */
1998            else if (eState == OMX_StateWaitForResources) {
1999                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->WaitForResources\n");
2000                post_event(OMX_EventError,OMX_ErrorSameState,
2001                        OMX_COMPONENT_GENERATE_EVENT);
2002                eRet = OMX_ErrorSameState;
2003            }
2004            /* Requesting transition from WaitForResources to Executing */
2005            else if (eState == OMX_StateExecuting) {
2006                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Executing\n");
2007                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2008                        OMX_COMPONENT_GENERATE_EVENT);
2009                eRet = OMX_ErrorIncorrectStateTransition;
2010            }
2011            /* Requesting transition from WaitForResources to Pause */
2012            else if (eState == OMX_StatePause) {
2013                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Pause\n");
2014                post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
2015                        OMX_COMPONENT_GENERATE_EVENT);
2016                eRet = OMX_ErrorIncorrectStateTransition;
2017            }
2018            /* Requesting transition from WaitForResources to Invalid */
2019            else if (eState == OMX_StateInvalid) {
2020                DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): WaitForResources-->Invalid\n");
2021                post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
2022                eRet = OMX_ErrorInvalidState;
2023            }
2024
2025            /* Requesting transition from WaitForResources to Loaded -
2026               is NOT tested by Khronos TS */
2027
2028        } else {
2029            DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): %d --> %d(Not Handled)\n",m_state,eState);
2030            eRet = OMX_ErrorBadParameter;
2031        }
2032    }
2033    /********************************/
2034    /* Current State is Invalid */
2035    /*******************************/
2036    else if (m_state == OMX_StateInvalid) {
2037        /* State Transition from Inavlid to any state */
2038        if (eState == (OMX_StateLoaded || OMX_StateWaitForResources
2039                    || OMX_StateIdle || OMX_StateExecuting
2040                    || OMX_StatePause || OMX_StateInvalid)) {
2041            DEBUG_PRINT_ERROR("ERROR::send_command_proxy(): Invalid -->Loaded\n");
2042            post_event(OMX_EventError,OMX_ErrorInvalidState,\
2043                    OMX_COMPONENT_GENERATE_EVENT);
2044            eRet = OMX_ErrorInvalidState;
2045        }
2046    } else if (cmd == OMX_CommandFlush) {
2047        DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandFlush issued "
2048                "with param1: %d", param1);
2049
2050        if (OMX_CORE_INPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2051            BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
2052        }
2053
2054        if (OMX_CORE_OUTPUT_PORT_INDEX == param1 || OMX_ALL == param1) {
2055            BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
2056        }
2057
2058        if (!sem_posted) {
2059            sem_posted = 1;
2060            DEBUG_PRINT_LOW("Set the Semaphore");
2061            sem_post (&m_cmd_lock);
2062            execute_omx_flush(param1);
2063        }
2064
2065        bFlag = 0;
2066    } else if ( cmd == OMX_CommandPortEnable) {
2067        DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortEnable issued "
2068                "with param1: %d", param1);
2069
2070        if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2071            m_inp_bEnabled = OMX_TRUE;
2072
2073            if ( (m_state == OMX_StateLoaded &&
2074                        !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2075                    || allocate_input_done()) {
2076                post_event(OMX_CommandPortEnable,OMX_CORE_INPUT_PORT_INDEX,
2077                        OMX_COMPONENT_GENERATE_EVENT);
2078            } else {
2079                DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending");
2080                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
2081                // Skip the event notification
2082                bFlag = 0;
2083            }
2084        }
2085
2086        if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2087            DEBUG_PRINT_HIGH("Enable output Port command recieved");
2088            m_out_bEnabled = OMX_TRUE;
2089
2090            if ( (m_state == OMX_StateLoaded &&
2091                        !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2092                    || (allocate_output_done())) {
2093                post_event(OMX_CommandPortEnable,OMX_CORE_OUTPUT_PORT_INDEX,
2094                        OMX_COMPONENT_GENERATE_EVENT);
2095
2096            } else {
2097                DEBUG_PRINT_HIGH("send_command_proxy(): Disabled-->Enabled Pending");
2098                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2099                // Skip the event notification
2100                bFlag = 0;
2101            }
2102        }
2103    } else if (cmd == OMX_CommandPortDisable) {
2104        DEBUG_PRINT_HIGH("send_command_proxy(): OMX_CommandPortDisable issued "
2105                "with param1: %d", param1);
2106
2107        if (param1 == OMX_CORE_INPUT_PORT_INDEX || param1 == OMX_ALL) {
2108            m_inp_bEnabled = OMX_FALSE;
2109
2110            if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2111                    && release_input_done()) {
2112                post_event(OMX_CommandPortDisable,OMX_CORE_INPUT_PORT_INDEX,
2113                        OMX_COMPONENT_GENERATE_EVENT);
2114            } else {
2115                BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
2116
2117                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2118                    if (!sem_posted) {
2119                        sem_posted = 1;
2120                        sem_post (&m_cmd_lock);
2121                    }
2122
2123                    execute_omx_flush(OMX_CORE_INPUT_PORT_INDEX);
2124                }
2125
2126                // Skip the event notification
2127                bFlag = 0;
2128            }
2129        }
2130
2131        if (param1 == OMX_CORE_OUTPUT_PORT_INDEX || param1 == OMX_ALL) {
2132            m_out_bEnabled = OMX_FALSE;
2133            DEBUG_PRINT_HIGH("Disable output Port command recieved");
2134
2135            if ((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
2136                    && release_output_done()) {
2137                post_event(OMX_CommandPortDisable,OMX_CORE_OUTPUT_PORT_INDEX,\
2138                        OMX_COMPONENT_GENERATE_EVENT);
2139            } else {
2140                BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
2141
2142                if (m_state == OMX_StatePause ||m_state == OMX_StateExecuting) {
2143                    if (!sem_posted) {
2144                        sem_posted = 1;
2145                        sem_post (&m_cmd_lock);
2146                    }
2147
2148                    BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_IN_DISABLE_PENDING);
2149                    execute_omx_flush(OMX_CORE_OUTPUT_PORT_INDEX);
2150                }
2151
2152                // Skip the event notification
2153                bFlag = 0;
2154
2155            }
2156        }
2157    } else {
2158        DEBUG_PRINT_ERROR("Error: Invalid Command other than StateSet (%d)\n",cmd);
2159        eRet = OMX_ErrorNotImplemented;
2160    }
2161
2162    if (eRet == OMX_ErrorNone && bFlag) {
2163        post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
2164    }
2165
2166    if (!sem_posted) {
2167        sem_post(&m_cmd_lock);
2168    }
2169
2170    return eRet;
2171}
2172
2173/* ======================================================================
2174   FUNCTION
2175   omx_vdec::ExecuteOmxFlush
2176
2177   DESCRIPTION
2178   Executes the OMX flush.
2179
2180   PARAMETERS
2181   flushtype - input flush(1)/output flush(0)/ both.
2182
2183   RETURN VALUE
2184   true/false
2185
2186   ========================================================================== */
2187bool omx_vdec::execute_omx_flush(OMX_U32 flushType)
2188{
2189    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
2190    enum vdec_bufferflush flush_dir;
2191    bool bRet = false;
2192
2193    switch (flushType) {
2194        case OMX_CORE_INPUT_PORT_INDEX:
2195            input_flush_progress = true;
2196            flush_dir = VDEC_FLUSH_TYPE_INPUT;
2197            break;
2198        case OMX_CORE_OUTPUT_PORT_INDEX:
2199            output_flush_progress = true;
2200            flush_dir = VDEC_FLUSH_TYPE_OUTPUT;
2201            break;
2202        default:
2203            input_flush_progress = true;
2204            output_flush_progress = true;
2205            flush_dir = VDEC_FLUSH_TYPE_ALL;
2206    }
2207
2208    ioctl_msg.in = &flush_dir;
2209    ioctl_msg.out = NULL;
2210
2211    if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_CMD_FLUSH, &ioctl_msg) < 0) {
2212        DEBUG_PRINT_ERROR("\n Flush Port (%d) Failed ", (int)flush_dir);
2213        bRet = false;
2214    }
2215
2216    return bRet;
2217}
2218/*=========================================================================
2219FUNCTION : execute_output_flush
2220
2221DESCRIPTION
2222Executes the OMX flush at OUTPUT PORT.
2223
2224PARAMETERS
2225None.
2226
2227RETURN VALUE
2228true/false
2229==========================================================================*/
2230bool omx_vdec::execute_output_flush()
2231{
2232    unsigned      p1 = 0; // Parameter - 1
2233    unsigned      p2 = 0; // Parameter - 2
2234    unsigned      ident = 0;
2235    bool bRet = true;
2236
2237    /*Generate FBD for all Buffers in the FTBq*/
2238    pthread_mutex_lock(&m_lock);
2239    DEBUG_PRINT_HIGH("Initiate Output Flush");
2240
2241    while (m_ftb_q.m_size) {
2242        DEBUG_PRINT_HIGH("Buffer queue size %d pending buf cnt %d",
2243                m_ftb_q.m_size,pending_output_buffers);
2244        m_ftb_q.pop_entry(&p1,&p2,&ident);
2245        DEBUG_PRINT_HIGH("ID(%x) P1(%x) P2(%x)", ident, p1, p2);
2246
2247        if (ident == m_fill_output_msg ) {
2248            m_cb.FillBufferDone(&m_cmp, m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2249        } else if (ident == OMX_COMPONENT_GENERATE_FBD) {
2250            fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2251        }
2252    }
2253
2254    pthread_mutex_unlock(&m_lock);
2255    output_flush_progress = false;
2256
2257    if (arbitrary_bytes) {
2258        prev_ts = LLONG_MAX;
2259        rst_prev_ts = true;
2260    }
2261
2262    DEBUG_PRINT_HIGH("OMX flush o/p Port complete PenBuf(%d)", pending_output_buffers);
2263    return bRet;
2264}
2265/*=========================================================================
2266FUNCTION : execute_input_flush
2267
2268DESCRIPTION
2269Executes the OMX flush at INPUT PORT.
2270
2271PARAMETERS
2272None.
2273
2274RETURN VALUE
2275true/false
2276==========================================================================*/
2277bool omx_vdec::execute_input_flush()
2278{
2279    unsigned       i =0;
2280    unsigned      p1 = 0; // Parameter - 1
2281    unsigned      p2 = 0; // Parameter - 2
2282    unsigned      ident = 0;
2283    bool bRet = true;
2284
2285    /*Generate EBD for all Buffers in the ETBq*/
2286    DEBUG_PRINT_HIGH("Initiate Input Flush");
2287
2288    pthread_mutex_lock(&m_lock);
2289    DEBUG_PRINT_LOW("Check if the Queue is empty");
2290
2291    while (m_etb_q.m_size) {
2292        m_etb_q.pop_entry(&p1,&p2,&ident);
2293
2294        if (ident == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2295            DEBUG_PRINT_HIGH("Flush Input Heap Buffer %p",(OMX_BUFFERHEADERTYPE *)p2);
2296            m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p2);
2297        } else if (ident == OMX_COMPONENT_GENERATE_ETB) {
2298            pending_input_buffers++;
2299            DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_ETB %p, pending_input_buffers %d",
2300                    (OMX_BUFFERHEADERTYPE *)p2, pending_input_buffers);
2301            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
2302        } else if (ident == OMX_COMPONENT_GENERATE_EBD) {
2303            DEBUG_PRINT_HIGH("Flush Input OMX_COMPONENT_GENERATE_EBD %p",
2304                    (OMX_BUFFERHEADERTYPE *)p1);
2305            empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
2306        }
2307    }
2308
2309    time_stamp_dts.flush_timestamp();
2310
2311    /*Check if Heap Buffers are to be flushed*/
2312    if (arbitrary_bytes && !(codec_config_flag)) {
2313        DEBUG_PRINT_HIGH("Reset all the variables before flusing");
2314        h264_scratch.nFilledLen = 0;
2315        nal_count = 0;
2316        look_ahead_nal = false;
2317        frame_count = 0;
2318        h264_last_au_ts = LLONG_MAX;
2319        h264_last_au_flags = 0;
2320        memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
2321        m_demux_entries = 0;
2322        DEBUG_PRINT_HIGH("Initialize parser");
2323
2324        if (m_frame_parser.mutils) {
2325            m_frame_parser.mutils->initialize_frame_checking_environment();
2326        }
2327
2328        while (m_input_pending_q.m_size) {
2329            m_input_pending_q.pop_entry(&p1,&p2,&ident);
2330            m_cb.EmptyBufferDone(&m_cmp ,m_app_data, (OMX_BUFFERHEADERTYPE *)p1);
2331        }
2332
2333        if (psource_frame) {
2334            m_cb.EmptyBufferDone(&m_cmp ,m_app_data,psource_frame);
2335            psource_frame = NULL;
2336        }
2337
2338        if (pdest_frame) {
2339            pdest_frame->nFilledLen = 0;
2340            m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
2341            pdest_frame = NULL;
2342        }
2343
2344        m_frame_parser.flush();
2345    } else if (codec_config_flag) {
2346        DEBUG_PRINT_HIGH("frame_parser flushing skipped due to codec config buffer "
2347                "is not sent to the driver yet");
2348    }
2349
2350    pthread_mutex_unlock(&m_lock);
2351    input_flush_progress = false;
2352
2353    if (!arbitrary_bytes) {
2354        prev_ts = LLONG_MAX;
2355        rst_prev_ts = true;
2356    }
2357
2358#ifdef _ANDROID_
2359
2360    if (m_debug_timestamp) {
2361        m_timestamp_list.reset_ts_list();
2362    }
2363
2364#endif
2365    DEBUG_PRINT_HIGH("OMX flush i/p Port complete PenBuf(%d)", pending_input_buffers);
2366    return bRet;
2367}
2368
2369
2370/* ======================================================================
2371   FUNCTION
2372   omx_vdec::SendCommandEvent
2373
2374   DESCRIPTION
2375   Send the event to decoder pipe.  This is needed to generate the callbacks
2376   in decoder thread context.
2377
2378   PARAMETERS
2379   None.
2380
2381   RETURN VALUE
2382   true/false
2383
2384   ========================================================================== */
2385bool omx_vdec::post_event(unsigned int p1,
2386        unsigned int p2,
2387        unsigned int id)
2388{
2389    bool bRet      =                      false;
2390
2391
2392    pthread_mutex_lock(&m_lock);
2393
2394    if (id == m_fill_output_msg ||
2395            id == OMX_COMPONENT_GENERATE_FBD) {
2396        m_ftb_q.insert_entry(p1,p2,id);
2397    } else if (id == OMX_COMPONENT_GENERATE_ETB ||
2398            id == OMX_COMPONENT_GENERATE_EBD ||
2399            id == OMX_COMPONENT_GENERATE_ETB_ARBITRARY) {
2400        m_etb_q.insert_entry(p1,p2,id);
2401    } else {
2402        m_cmd_q.insert_entry(p1,p2,id);
2403    }
2404
2405    bRet = true;
2406    DEBUG_PRINT_LOW("Value of this pointer in post_event %p",this);
2407    post_message(this, id);
2408
2409    pthread_mutex_unlock(&m_lock);
2410
2411    return bRet;
2412}
2413#ifdef MAX_RES_720P
2414OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_720p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2415{
2416    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2417
2418    if (!profileLevelType)
2419        return OMX_ErrorBadParameter;
2420
2421    if (profileLevelType->nPortIndex == 0) {
2422        if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2423            if (profileLevelType->nProfileIndex == 0) {
2424                profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2425                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
2426
2427            } else if (profileLevelType->nProfileIndex == 1) {
2428                profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2429                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
2430            } else if (profileLevelType->nProfileIndex == 2) {
2431                profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2432                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel31;
2433            } else {
2434                DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
2435                        profileLevelType->nProfileIndex);
2436                eRet = OMX_ErrorNoMore;
2437            }
2438        } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2439            if (profileLevelType->nProfileIndex == 0) {
2440                profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2441                profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
2442            } else {
2443                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2444                eRet = OMX_ErrorNoMore;
2445            }
2446        } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2447            if (profileLevelType->nProfileIndex == 0) {
2448                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2449                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
2450            } else if (profileLevelType->nProfileIndex == 1) {
2451                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2452                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
2453            } else {
2454                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2455                eRet = OMX_ErrorNoMore;
2456            }
2457        }
2458    } else {
2459        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
2460        eRet = OMX_ErrorBadPortIndex;
2461    }
2462
2463    return eRet;
2464}
2465#endif
2466#ifdef MAX_RES_1080P
2467OMX_ERRORTYPE omx_vdec::get_supported_profile_level_for_1080p(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
2468{
2469    OMX_ERRORTYPE eRet = OMX_ErrorNoMore;
2470
2471    if (!profileLevelType)
2472        return OMX_ErrorBadParameter;
2473
2474    if (profileLevelType->nPortIndex == 0) {
2475        if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
2476            if (profileLevelType->nProfileIndex == 0) {
2477                profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
2478                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
2479
2480            } else if (profileLevelType->nProfileIndex == 1) {
2481                profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
2482                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
2483            } else if (profileLevelType->nProfileIndex == 2) {
2484                profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
2485                profileLevelType->eLevel   = OMX_VIDEO_AVCLevel4;
2486            } else {
2487                DEBUG_PRINT_HIGH("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d",
2488                        profileLevelType->nProfileIndex);
2489                eRet = OMX_ErrorNoMore;
2490            }
2491        } else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))) {
2492            if (profileLevelType->nProfileIndex == 0) {
2493                profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
2494                profileLevelType->eLevel   = OMX_VIDEO_H263Level70;
2495            } else {
2496                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2497                eRet = OMX_ErrorNoMore;
2498            }
2499        } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
2500            if (profileLevelType->nProfileIndex == 0) {
2501                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
2502                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
2503            } else if (profileLevelType->nProfileIndex == 1) {
2504                profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
2505                profileLevelType->eLevel   = OMX_VIDEO_MPEG4Level5;
2506            } else {
2507                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2508                eRet = OMX_ErrorNoMore;
2509            }
2510        } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
2511            if (profileLevelType->nProfileIndex == 0) {
2512                profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileSimple;
2513                profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
2514            } else if (profileLevelType->nProfileIndex == 1) {
2515                profileLevelType->eProfile = OMX_VIDEO_MPEG2ProfileMain;
2516                profileLevelType->eLevel   = OMX_VIDEO_MPEG2LevelHL;
2517            } else {
2518                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
2519                eRet = OMX_ErrorNoMore;
2520            }
2521        } else {
2522            DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore\n");
2523            eRet = OMX_ErrorNoMore;
2524        }
2525    } else {
2526        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
2527        eRet = OMX_ErrorBadPortIndex;
2528    }
2529
2530    return eRet;
2531}
2532#endif
2533
2534/* ======================================================================
2535   FUNCTION
2536   omx_vdec::GetParameter
2537
2538   DESCRIPTION
2539   OMX Get Parameter method implementation
2540
2541   PARAMETERS
2542   <TBD>.
2543
2544   RETURN VALUE
2545   Error None if successful.
2546
2547   ========================================================================== */
2548OMX_ERRORTYPE  omx_vdec::get_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2549        OMX_IN OMX_INDEXTYPE paramIndex,
2550        OMX_INOUT OMX_PTR     paramData)
2551{
2552    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2553
2554    DEBUG_PRINT_LOW("get_parameter:");
2555
2556    if (m_state == OMX_StateInvalid) {
2557        DEBUG_PRINT_ERROR("Get Param in Invalid State\n");
2558        return OMX_ErrorInvalidState;
2559    }
2560
2561    if (paramData == NULL) {
2562        DEBUG_PRINT_ERROR("\n Get Param in Invalid paramData");
2563        return OMX_ErrorBadParameter;
2564    }
2565
2566    switch (paramIndex) {
2567        case OMX_IndexParamPortDefinition:
2568            {
2569                OMX_PARAM_PORTDEFINITIONTYPE *portDefn =
2570                    (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2571                eRet = update_portdef(portDefn);
2572
2573                if (eRet == OMX_ErrorNone)
2574                    m_port_def = *portDefn;
2575
2576                DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamPortDefinition: "
2577                        "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), "
2578                        "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), "
2579                        "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), "
2580                        "bBuffersContiguous (%d), nBufferAlignment (%d), "
2581                        "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), "
2582                        "eColorFormat (0x%x)" , (int)portDefn->nPortIndex,
2583                        (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight,
2584                        (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight,
2585                        (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate,
2586                        (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin,
2587                        (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous,
2588                        (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated,
2589                        (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat);
2590                break;
2591            }
2592        case OMX_IndexParamVideoInit:
2593            {
2594                OMX_PORT_PARAM_TYPE *portParamType =
2595                    (OMX_PORT_PARAM_TYPE *) paramData;
2596                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
2597
2598                portParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2599                portParamType->nSize = sizeof(portParamType);
2600                portParamType->nPorts           = 2;
2601                portParamType->nStartPortNumber = 0;
2602                break;
2603            }
2604        case OMX_IndexParamVideoPortFormat:
2605            {
2606                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
2607                    (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
2608                portFmt->nVersion.nVersion = OMX_SPEC_VERSION;
2609                portFmt->nSize             = sizeof(portFmt);
2610
2611                if (0 == portFmt->nPortIndex) {
2612                    if (0 == portFmt->nIndex) {
2613                        portFmt->eColorFormat =  OMX_COLOR_FormatUnused;
2614                        portFmt->eCompressionFormat = eCompressionFormat;
2615                    } else {
2616                        DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoPortFormat:"\
2617                                " NoMore compression formats\n");
2618                        eRet =  OMX_ErrorNoMore;
2619                    }
2620                } else if (1 == portFmt->nPortIndex) {
2621                    portFmt->eCompressionFormat =  OMX_VIDEO_CodingUnused;
2622
2623                    if (0 == portFmt->nIndex)
2624                        portFmt->eColorFormat = (OMX_COLOR_FORMATTYPE)
2625                            QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
2626                    else if (1 == portFmt->nIndex) {
2627                        portFmt->eColorFormat = OMX_COLOR_FormatYUV420Planar;
2628                    } else {
2629                        DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat:"\
2630                                " NoMore Color formats\n");
2631                        eRet =  OMX_ErrorNoMore;
2632                    }
2633                } else {
2634                    DEBUG_PRINT_ERROR("get_parameter: Bad port index %d\n",
2635                            (int)portFmt->nPortIndex);
2636                    eRet = OMX_ErrorBadPortIndex;
2637                }
2638
2639                DEBUG_PRINT_HIGH("Get_parameter: OMX_IndexParamVideoPortFormat: "
2640                        "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), "
2641                        "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex,
2642                        (int)portFmt->nIndex, (int)portFmt->eCompressionFormat,
2643                        (int)portFmt->eColorFormat, (int)portFmt->xFramerate);
2644                break;
2645            }
2646            /*Component should support this port definition*/
2647        case OMX_IndexParamAudioInit:
2648            {
2649                OMX_PORT_PARAM_TYPE *audioPortParamType =
2650                    (OMX_PORT_PARAM_TYPE *) paramData;
2651                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
2652                audioPortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2653                audioPortParamType->nSize = sizeof(audioPortParamType);
2654                audioPortParamType->nPorts           = 0;
2655                audioPortParamType->nStartPortNumber = 0;
2656                break;
2657            }
2658            /*Component should support this port definition*/
2659        case OMX_IndexParamImageInit:
2660            {
2661                OMX_PORT_PARAM_TYPE *imagePortParamType =
2662                    (OMX_PORT_PARAM_TYPE *) paramData;
2663                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
2664                imagePortParamType->nVersion.nVersion = OMX_SPEC_VERSION;
2665                imagePortParamType->nSize = sizeof(imagePortParamType);
2666                imagePortParamType->nPorts           = 0;
2667                imagePortParamType->nStartPortNumber = 0;
2668                break;
2669
2670            }
2671            /*Component should support this port definition*/
2672        case OMX_IndexParamOtherInit:
2673            {
2674                DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamOtherInit %08x\n",
2675                        paramIndex);
2676                eRet =OMX_ErrorUnsupportedIndex;
2677                break;
2678            }
2679        case OMX_IndexParamStandardComponentRole:
2680            {
2681                OMX_PARAM_COMPONENTROLETYPE *comp_role;
2682                comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
2683                comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
2684                comp_role->nSize = sizeof(*comp_role);
2685
2686                DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",
2687                        paramIndex);
2688                strlcpy((char*)comp_role->cRole,(const char*)m_cRole,
2689                        OMX_MAX_STRINGNAME_SIZE);
2690                break;
2691            }
2692            /* Added for parameter test */
2693        case OMX_IndexParamPriorityMgmt:
2694            {
2695
2696                OMX_PRIORITYMGMTTYPE *priorityMgmType =
2697                    (OMX_PRIORITYMGMTTYPE *) paramData;
2698                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
2699                priorityMgmType->nVersion.nVersion = OMX_SPEC_VERSION;
2700                priorityMgmType->nSize = sizeof(priorityMgmType);
2701
2702                break;
2703            }
2704            /* Added for parameter test */
2705        case OMX_IndexParamCompBufferSupplier:
2706            {
2707                OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType =
2708                    (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
2709                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
2710
2711                bufferSupplierType->nSize = sizeof(bufferSupplierType);
2712                bufferSupplierType->nVersion.nVersion = OMX_SPEC_VERSION;
2713
2714                if (0 == bufferSupplierType->nPortIndex)
2715                    bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2716                else if (1 == bufferSupplierType->nPortIndex)
2717                    bufferSupplierType->nPortIndex = OMX_BufferSupplyUnspecified;
2718                else
2719                    eRet = OMX_ErrorBadPortIndex;
2720
2721
2722                break;
2723            }
2724        case OMX_IndexParamVideoAvc:
2725            {
2726                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc %08x\n",
2727                        paramIndex);
2728                break;
2729            }
2730        case OMX_IndexParamVideoH263:
2731            {
2732                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x\n",
2733                        paramIndex);
2734                break;
2735            }
2736        case OMX_IndexParamVideoMpeg4:
2737            {
2738                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x\n",
2739                        paramIndex);
2740                break;
2741            }
2742        case OMX_IndexParamVideoMpeg2:
2743            {
2744                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x\n",
2745                        paramIndex);
2746                break;
2747            }
2748        case OMX_IndexParamVideoProfileLevelQuerySupported:
2749            {
2750                DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x\n", paramIndex);
2751                OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType =
2752                    (OMX_VIDEO_PARAM_PROFILELEVELTYPE *)paramData;
2753#ifdef MAX_RES_720P
2754                eRet = get_supported_profile_level_for_720p(profileLevelType);
2755#endif
2756#ifdef MAX_RES_1080P
2757                eRet = get_supported_profile_level_for_1080p(profileLevelType);
2758#endif
2759                break;
2760            }
2761#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2762        case OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage:
2763            {
2764                DEBUG_PRINT_HIGH("get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage");
2765                GetAndroidNativeBufferUsageParams* nativeBuffersUsage = (GetAndroidNativeBufferUsageParams *) paramData;
2766
2767                if (nativeBuffersUsage->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
2768#ifdef USE_ION
2769#if defined (MAX_RES_720P)
2770                    nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_CAMERA_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
2771                    DEBUG_PRINT_HIGH("ION:720P: nUsage 0x%x",nativeBuffersUsage->nUsage);
2772#else
2773
2774                    if (secure_mode) {
2775                        nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP | GRALLOC_USAGE_PROTECTED |
2776                                GRALLOC_USAGE_PRIVATE_UNCACHED);
2777                        DEBUG_PRINT_HIGH("ION:secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage);
2778                    } else {
2779                        nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_MM_HEAP |
2780                                GRALLOC_USAGE_PRIVATE_IOMMU_HEAP);
2781                        DEBUG_PRINT_HIGH("ION:non_secure_mode: nUsage 0x%x",nativeBuffersUsage->nUsage);
2782                    }
2783
2784#endif //(MAX_RES_720P)
2785#else // USE_ION
2786#if defined (MAX_RES_720P) ||  defined (MAX_RES_1080P_EBI)
2787                    nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_ADSP_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
2788                    DEBUG_PRINT_HIGH("720P/1080P_EBI: nUsage 0x%x",nativeBuffersUsage->nUsage);
2789#elif MAX_RES_1080P
2790                    nativeBuffersUsage->nUsage = (GRALLOC_USAGE_PRIVATE_SMI_HEAP | GRALLOC_USAGE_PRIVATE_UNCACHED);
2791                    DEBUG_PRINT_HIGH("1080P: nUsage 0x%x",nativeBuffersUsage->nUsage);
2792#endif
2793#endif // USE_ION
2794                } else {
2795                    DEBUG_PRINT_ERROR("\n get_parameter: OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage failed!");
2796                    eRet = OMX_ErrorBadParameter;
2797                }
2798            }
2799            break;
2800#endif
2801
2802        default:
2803            {
2804                DEBUG_PRINT_ERROR("get_parameter: unknown param %08x\n", paramIndex);
2805                eRet =OMX_ErrorUnsupportedIndex;
2806            }
2807
2808    }
2809
2810    DEBUG_PRINT_LOW("get_parameter returning WxH(%d x %d) SxSH(%d x %d)",
2811            drv_ctx.video_resolution.frame_width,
2812            drv_ctx.video_resolution.frame_height,
2813            drv_ctx.video_resolution.stride,
2814            drv_ctx.video_resolution.scan_lines);
2815
2816    return eRet;
2817}
2818
2819#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
2820OMX_ERRORTYPE omx_vdec::use_android_native_buffer(OMX_IN OMX_HANDLETYPE hComp, OMX_PTR data)
2821{
2822    DEBUG_PRINT_LOW("Inside use_android_native_buffer");
2823    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2824    UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)data;
2825
2826    if ((params == NULL) ||
2827            (params->nativeBuffer == NULL) ||
2828            (params->nativeBuffer->handle == NULL) ||
2829            !m_enable_android_native_buffers)
2830        return OMX_ErrorBadParameter;
2831
2832    m_use_android_native_buffers = OMX_TRUE;
2833    sp<android_native_buffer_t> nBuf = params->nativeBuffer;
2834    private_handle_t *handle = (private_handle_t *)nBuf->handle;
2835
2836    if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
2837        DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
2838                " expected %u, got %lu",
2839                drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
2840        return OMX_ErrorBadParameter;
2841    }
2842
2843    if (OMX_CORE_OUTPUT_PORT_INDEX == params->nPortIndex) { //android native buffers can be used only on Output port
2844        OMX_U8 *buffer = NULL;
2845
2846        if (!secure_mode) {
2847            buffer = (OMX_U8*)mmap(0, handle->size,
2848                    PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
2849
2850            if (buffer == MAP_FAILED) {
2851                DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
2852                return OMX_ErrorInsufficientResources;
2853            }
2854        }
2855
2856        eRet = use_buffer(hComp,params->bufferHeader,params->nPortIndex,data,handle->size,buffer);
2857    } else {
2858        eRet = OMX_ErrorBadParameter;
2859    }
2860
2861    return eRet;
2862}
2863#endif
2864/* ======================================================================
2865   FUNCTION
2866   omx_vdec::Setparameter
2867
2868   DESCRIPTION
2869   OMX Set Parameter method implementation.
2870
2871   PARAMETERS
2872   <TBD>.
2873
2874   RETURN VALUE
2875   OMX Error None if successful.
2876
2877   ========================================================================== */
2878OMX_ERRORTYPE  omx_vdec::set_parameter(OMX_IN OMX_HANDLETYPE     hComp,
2879        OMX_IN OMX_INDEXTYPE paramIndex,
2880        OMX_IN OMX_PTR        paramData)
2881{
2882    OMX_ERRORTYPE eRet = OMX_ErrorNone;
2883    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
2884
2885    if (m_state == OMX_StateInvalid) {
2886        DEBUG_PRINT_ERROR("Set Param in Invalid State\n");
2887        return OMX_ErrorInvalidState;
2888    }
2889
2890    if (paramData == NULL) {
2891        DEBUG_PRINT_ERROR("Get Param in Invalid paramData \n");
2892        return OMX_ErrorBadParameter;
2893    }
2894
2895    if ((m_state != OMX_StateLoaded) &&
2896            BITMASK_ABSENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING) &&
2897            (m_out_bEnabled == OMX_TRUE) &&
2898            BITMASK_ABSENT(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING) &&
2899            (m_inp_bEnabled == OMX_TRUE)) {
2900        DEBUG_PRINT_ERROR("Set Param in Invalid State \n");
2901        return OMX_ErrorIncorrectStateOperation;
2902    }
2903
2904    switch (paramIndex) {
2905        case OMX_IndexParamPortDefinition:
2906            {
2907                OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
2908                portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
2909                //TODO: Check if any allocate buffer/use buffer/useNativeBuffer has
2910                //been called.
2911                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition H= %d, W = %d",
2912                        (int)portDefn->format.video.nFrameHeight,
2913                        (int)portDefn->format.video.nFrameWidth);
2914
2915                if (OMX_DirOutput == portDefn->eDir) {
2916                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition OP port");
2917                    m_display_id = portDefn->format.video.pNativeWindow;
2918                    unsigned int buffer_size;
2919
2920                    if (!client_buffers.get_buffer_req(buffer_size)) {
2921                        DEBUG_PRINT_ERROR("\n Error in getting buffer requirements");
2922                        eRet = OMX_ErrorBadParameter;
2923                    } else {
2924                        if ( portDefn->nBufferCountActual >= drv_ctx.op_buf.mincount &&
2925                                portDefn->nBufferSize >=  buffer_size) {
2926                            drv_ctx.op_buf.actualcount = portDefn->nBufferCountActual;
2927                            drv_ctx.op_buf.buffer_size = portDefn->nBufferSize;
2928                            eRet = set_buffer_req(&drv_ctx.op_buf);
2929
2930                            if (eRet == OMX_ErrorNone)
2931                                m_port_def = *portDefn;
2932                        } else {
2933                            DEBUG_PRINT_HIGH("ERROR: OP Requirements(#%d: %u) Requested(#%d: %u)\n",
2934                                    drv_ctx.op_buf.mincount, drv_ctx.op_buf.buffer_size,
2935                                    portDefn->nBufferCountActual, portDefn->nBufferSize);
2936                            eRet = OMX_ErrorBadParameter;
2937                        }
2938                    }
2939                } else if (OMX_DirInput == portDefn->eDir) {
2940                    if ((portDefn->format.video.xFramerate >> 16) > 0 &&
2941                            (portDefn->format.video.xFramerate >> 16) <= MAX_SUPPORTED_FPS) {
2942                        // Frame rate only should be set if this is a "known value" or to
2943                        // activate ts prediction logic (arbitrary mode only) sending input
2944                        // timestamps with max value (LLONG_MAX).
2945                        DEBUG_PRINT_LOW("set_parameter: frame rate set by omx client : %d",
2946                                portDefn->format.video.xFramerate >> 16);
2947                        Q16ToFraction(portDefn->format.video.xFramerate, drv_ctx.frame_rate.fps_numerator,
2948                                drv_ctx.frame_rate.fps_denominator);
2949
2950                        if (!drv_ctx.frame_rate.fps_numerator) {
2951                            DEBUG_PRINT_ERROR("Numerator is zero setting to 30");
2952                            drv_ctx.frame_rate.fps_numerator = 30;
2953                        }
2954
2955                        if (drv_ctx.frame_rate.fps_denominator)
2956                            drv_ctx.frame_rate.fps_numerator = (int)
2957                                drv_ctx.frame_rate.fps_numerator / drv_ctx.frame_rate.fps_denominator;
2958
2959                        drv_ctx.frame_rate.fps_denominator = 1;
2960                        frm_int = drv_ctx.frame_rate.fps_denominator * 1e6 /
2961                            drv_ctx.frame_rate.fps_numerator;
2962                        ioctl_msg.in = &drv_ctx.frame_rate;
2963
2964                        if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
2965                                    (void*)&ioctl_msg) < 0) {
2966                            DEBUG_PRINT_ERROR("Setting frame rate to driver failed");
2967                        }
2968
2969                        DEBUG_PRINT_LOW("set_parameter: frm_int(%u) fps(%.2f)",
2970                                frm_int, drv_ctx.frame_rate.fps_numerator /
2971                                (float)drv_ctx.frame_rate.fps_denominator);
2972                    }
2973
2974                    DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPortDefinition IP port");
2975
2976                    if (drv_ctx.video_resolution.frame_height !=
2977                            portDefn->format.video.nFrameHeight ||
2978                            drv_ctx.video_resolution.frame_width  !=
2979                            portDefn->format.video.nFrameWidth) {
2980                        DEBUG_PRINT_LOW("SetParam IP: WxH(%d x %d)",
2981                                portDefn->format.video.nFrameWidth,
2982                                portDefn->format.video.nFrameHeight);
2983
2984                        if (portDefn->format.video.nFrameHeight != 0x0 &&
2985                                portDefn->format.video.nFrameWidth != 0x0) {
2986                            drv_ctx.video_resolution.frame_height =
2987                                drv_ctx.video_resolution.scan_lines =
2988                                portDefn->format.video.nFrameHeight;
2989                            drv_ctx.video_resolution.frame_width =
2990                                drv_ctx.video_resolution.stride =
2991                                portDefn->format.video.nFrameWidth;
2992                            ioctl_msg.in = &drv_ctx.video_resolution;
2993                            ioctl_msg.out = NULL;
2994
2995                            if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICRES,
2996                                        (void*)&ioctl_msg) < 0) {
2997                                DEBUG_PRINT_ERROR("\n Set Resolution failed");
2998                                eRet = OMX_ErrorUnsupportedSetting;
2999                            } else
3000                                eRet = get_buffer_req(&drv_ctx.op_buf);
3001                        }
3002                    } else if (portDefn->nBufferCountActual >= drv_ctx.ip_buf.mincount
3003                            && portDefn->nBufferSize == (drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH)) {
3004                        drv_ctx.ip_buf.actualcount = portDefn->nBufferCountActual;
3005                        drv_ctx.ip_buf.buffer_size = portDefn->nBufferSize + DEVICE_SCRATCH;
3006                        eRet = set_buffer_req(&drv_ctx.ip_buf);
3007                    } else {
3008                        DEBUG_PRINT_ERROR("ERROR: IP Requirements(#%d: %u) Requested(#%d: %u)\n",
3009                                drv_ctx.ip_buf.mincount, drv_ctx.ip_buf.buffer_size,
3010                                portDefn->nBufferCountActual, portDefn->nBufferSize);
3011                        eRet = OMX_ErrorBadParameter;
3012                    }
3013                } else if (portDefn->eDir ==  OMX_DirMax) {
3014                    DEBUG_PRINT_ERROR(" Set_parameter: Bad Port idx %d",
3015                            (int)portDefn->nPortIndex);
3016                    eRet = OMX_ErrorBadPortIndex;
3017                }
3018
3019                DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamPortDefinition: "
3020                        "nPortIndex (%d), nFrameWidth (%d), nFrameHeight (%d), "
3021                        "nStride (%d), nSliceHeight (%d), nBitrate (%d), xFramerate (0x%x), "
3022                        "nBufferSize (%d), nBufferCountMin (%d), nBufferCountActual (%d), "
3023                        "bBuffersContiguous (%d), nBufferAlignment (%d), "
3024                        "bEnabled (%d), bPopulated (%d), eCompressionFormat (0x%x), "
3025                        "eColorFormat (0x%x)" , (int)portDefn->nPortIndex,
3026                        (int)portDefn->format.video.nFrameWidth, (int)portDefn->format.video.nFrameHeight,
3027                        (int)portDefn->format.video.nStride, (int)portDefn->format.video.nSliceHeight,
3028                        (int)portDefn->format.video.nBitrate, (int)portDefn->format.video.xFramerate,
3029                        (int)portDefn->nBufferSize, (int)portDefn->nBufferCountMin,
3030                        (int)portDefn->nBufferCountActual, (int)portDefn->bBuffersContiguous,
3031                        (int)portDefn->nBufferAlignment, (int)portDefn->bEnabled, (int)portDefn->bPopulated,
3032                        (int)portDefn->format.video.eCompressionFormat, (int)portDefn->format.video.eColorFormat);
3033            }
3034            break;
3035        case OMX_IndexParamVideoPortFormat:
3036            {
3037                OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
3038                    (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
3039
3040                if (1 == portFmt->nPortIndex) {
3041                    enum vdec_output_fromat op_format;
3042
3043                    if (portFmt->eColorFormat == OMX_COLOR_FormatYUV420SemiPlanar)
3044                        op_format = VDEC_YUV_FORMAT_NV12;
3045                    else if (portFmt->eColorFormat ==
3046                            QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka ||
3047                            portFmt->eColorFormat == OMX_COLOR_FormatYUV420Planar)
3048                        op_format = VDEC_YUV_FORMAT_TILE_4x2;
3049                    else
3050                        eRet = OMX_ErrorBadParameter;
3051
3052                    if (eRet == OMX_ErrorNone && drv_ctx.output_format != op_format) {
3053                        /*Set the output format*/
3054                        drv_ctx.output_format = op_format;
3055                        ioctl_msg.in = &drv_ctx.output_format;
3056                        ioctl_msg.out = NULL;
3057
3058                        if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_OUTPUT_FORMAT,
3059                                    (void*)&ioctl_msg) < 0) {
3060                            DEBUG_PRINT_ERROR("\n Set output format failed");
3061                            eRet = OMX_ErrorUnsupportedSetting;
3062                        } else {
3063                            eRet = get_buffer_req(&drv_ctx.op_buf);
3064                        }
3065                    }
3066
3067                    if (eRet == OMX_ErrorNone) {
3068                        if (!client_buffers.set_color_format(portFmt->eColorFormat)) {
3069                            DEBUG_PRINT_ERROR("\n Set color format failed");
3070                            eRet = OMX_ErrorBadParameter;
3071                        }
3072                    }
3073                }
3074
3075                DEBUG_PRINT_HIGH("Set_parameter: OMX_IndexParamVideoPortFormat: "
3076                        "nPortIndex (%d), nIndex (%d), eCompressionFormat (0x%x), "
3077                        "eColorFormat (0x%x), xFramerate (0x%x)", (int)portFmt->nPortIndex,
3078                        (int)portFmt->nIndex, (int)portFmt->eCompressionFormat,
3079                        (int)portFmt->eColorFormat, (int)portFmt->xFramerate);
3080            }
3081            break;
3082
3083        case OMX_QcomIndexPortDefn:
3084            {
3085                OMX_QCOM_PARAM_PORTDEFINITIONTYPE *portFmt =
3086                    (OMX_QCOM_PARAM_PORTDEFINITIONTYPE *) paramData;
3087                DEBUG_PRINT_LOW("set_parameter: OMX_IndexQcomParamPortDefinitionType %d",
3088                        portFmt->nFramePackingFormat);
3089
3090                /* Input port */
3091                if (portFmt->nPortIndex == 0) {
3092                    if (portFmt->nFramePackingFormat == OMX_QCOM_FramePacking_Arbitrary) {
3093                        if (secure_mode) {
3094                            arbitrary_bytes = false;
3095                            DEBUG_PRINT_ERROR("setparameter: cannot set to arbitary bytes mode in secure session");
3096                            eRet = OMX_ErrorUnsupportedSetting;
3097                        } else {
3098                            arbitrary_bytes = true;
3099                            DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes enabled");
3100                        }
3101                    } else if (portFmt->nFramePackingFormat ==
3102                            OMX_QCOM_FramePacking_OnlyOneCompleteFrame) {
3103                        arbitrary_bytes = false;
3104                        DEBUG_PRINT_HIGH("setparameter: arbitrary_bytes disabled");
3105                    } else {
3106                        DEBUG_PRINT_ERROR("Setparameter: unknown FramePacking format %d\n",
3107                                portFmt->nFramePackingFormat);
3108                        eRet = OMX_ErrorUnsupportedSetting;
3109                    }
3110                } else if (portFmt->nPortIndex == OMX_CORE_OUTPUT_PORT_INDEX) {
3111                    DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port");
3112
3113                    if ( (portFmt->nMemRegion > OMX_QCOM_MemRegionInvalid &&
3114                                portFmt->nMemRegion < OMX_QCOM_MemRegionMax) &&
3115                            portFmt->nCacheAttr == OMX_QCOM_CacheAttrNone) {
3116                        m_out_mem_region_smi = OMX_TRUE;
3117
3118                        if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3119                            DEBUG_PRINT_HIGH("set_parameter: OMX_IndexQcomParamPortDefinitionType OP Port: set use_output_pmem");
3120                            m_use_output_pmem = OMX_TRUE;
3121                        }
3122                    }
3123                }
3124            }
3125            break;
3126
3127        case OMX_IndexParamStandardComponentRole:
3128            {
3129                OMX_PARAM_COMPONENTROLETYPE *comp_role;
3130                comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
3131                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamStandardComponentRole %s",
3132                        comp_role->cRole);
3133
3134                if ((m_state == OMX_StateLoaded)&&
3135                        !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
3136                    DEBUG_PRINT_LOW("Set Parameter called in valid state");
3137                } else {
3138                    DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3139                    return OMX_ErrorIncorrectStateOperation;
3140                }
3141
3142                if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3143                    if (!strncmp((char*)comp_role->cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
3144                        strlcpy((char*)m_cRole,"video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3145                    } else {
3146                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3147                        eRet =OMX_ErrorUnsupportedSetting;
3148                    }
3149                } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3150                    if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
3151                        strlcpy((char*)m_cRole,"video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3152                    } else {
3153                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3154                        eRet = OMX_ErrorUnsupportedSetting;
3155                    }
3156                } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3157                    if (!strncmp((const char*)comp_role->cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
3158                        strlcpy((char*)m_cRole,"video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3159                    } else {
3160                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3161                        eRet =OMX_ErrorUnsupportedSetting;
3162                    }
3163                } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3164                    if (!strncmp((const char*)comp_role->cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
3165                        strlcpy((char*)m_cRole,"video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
3166                    } else {
3167                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3168                        eRet = OMX_ErrorUnsupportedSetting;
3169                    }
3170                }
3171
3172#ifdef MAX_RES_1080P
3173                else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
3174                        (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
3175                        )
3176#else
3177                else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE))
3178#endif
3179                {
3180
3181                    if (!strncmp((const char*)comp_role->cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE)) {
3182                        strlcpy((char*)m_cRole,"video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
3183                    } else {
3184                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3185                        eRet =OMX_ErrorUnsupportedSetting;
3186                    }
3187                } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
3188                        (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
3189                        ) {
3190                    if (!strncmp((const char*)comp_role->cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) {
3191                        strlcpy((char*)m_cRole,"video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3192                    } else {
3193                        DEBUG_PRINT_ERROR("Setparameter: unknown Index %s\n", comp_role->cRole);
3194                        eRet =OMX_ErrorUnsupportedSetting;
3195                    }
3196                } else {
3197                    DEBUG_PRINT_ERROR("Setparameter: unknown param %s\n", drv_ctx.kind);
3198                    eRet = OMX_ErrorInvalidComponentName;
3199                }
3200
3201                break;
3202            }
3203
3204        case OMX_IndexParamPriorityMgmt:
3205            {
3206                if (m_state != OMX_StateLoaded) {
3207                    DEBUG_PRINT_ERROR("Set Parameter called in Invalid State\n");
3208                    return OMX_ErrorIncorrectStateOperation;
3209                }
3210
3211                OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
3212                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d\n",
3213                        priorityMgmtype->nGroupID);
3214
3215                DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d\n",
3216                        priorityMgmtype->nGroupPriority);
3217
3218                m_priority_mgm.nGroupID = priorityMgmtype->nGroupID;
3219                m_priority_mgm.nGroupPriority = priorityMgmtype->nGroupPriority;
3220
3221                break;
3222            }
3223
3224        case OMX_IndexParamCompBufferSupplier:
3225            {
3226                OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
3227                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamCompBufferSupplier %d\n",
3228                        bufferSupplierType->eBufferSupplier);
3229
3230                if (bufferSupplierType->nPortIndex == 0 || bufferSupplierType->nPortIndex ==1)
3231                    m_buffer_supplier.eBufferSupplier = bufferSupplierType->eBufferSupplier;
3232
3233                else
3234
3235                    eRet = OMX_ErrorBadPortIndex;
3236
3237                break;
3238
3239            }
3240        case OMX_IndexParamVideoAvc:
3241            {
3242                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoAvc %d\n",
3243                        paramIndex);
3244                break;
3245            }
3246        case OMX_IndexParamVideoH263:
3247            {
3248                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d\n",
3249                        paramIndex);
3250                break;
3251            }
3252        case OMX_IndexParamVideoMpeg4:
3253            {
3254                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d\n",
3255                        paramIndex);
3256                break;
3257            }
3258        case OMX_IndexParamVideoMpeg2:
3259            {
3260                DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d\n",
3261                        paramIndex);
3262                break;
3263            }
3264        case OMX_QcomIndexParamVideoDecoderPictureOrder:
3265            {
3266                QOMX_VIDEO_DECODER_PICTURE_ORDER *pictureOrder =
3267                    (QOMX_VIDEO_DECODER_PICTURE_ORDER *)paramData;
3268                enum vdec_output_order pic_order = VDEC_ORDER_DISPLAY;
3269                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoDecoderPictureOrder %d\n",
3270                        pictureOrder->eOutputPictureOrder);
3271
3272                if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DISPLAY_ORDER)
3273                    pic_order = VDEC_ORDER_DISPLAY;
3274                else if (pictureOrder->eOutputPictureOrder == QOMX_VIDEO_DECODE_ORDER) {
3275                    pic_order = VDEC_ORDER_DECODE;
3276                    time_stamp_dts.set_timestamp_reorder_mode(false);
3277                } else
3278                    eRet = OMX_ErrorBadParameter;
3279
3280#ifdef MAX_RES_720P
3281
3282                if (drv_ctx.idr_only_decoding) {
3283                    if (pictureOrder->eOutputPictureOrder != QOMX_VIDEO_DECODE_ORDER) {
3284                        DEBUG_PRINT_HIGH("only decode order is supported for thumbnail mode");
3285                        eRet = OMX_ErrorBadParameter;
3286                    }
3287                }
3288
3289#endif
3290
3291                if (eRet == OMX_ErrorNone && pic_order != drv_ctx.picture_order) {
3292                    drv_ctx.picture_order = pic_order;
3293                    ioctl_msg.in = &drv_ctx.picture_order;
3294                    ioctl_msg.out = NULL;
3295
3296                    if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER,
3297                                (void*)&ioctl_msg) < 0) {
3298                        DEBUG_PRINT_ERROR("\n Set picture order failed");
3299                        eRet = OMX_ErrorUnsupportedSetting;
3300                    }
3301                }
3302
3303                break;
3304            }
3305        case OMX_QcomIndexParamConcealMBMapExtraData:
3306            {
3307                eRet = enable_extradata(VDEC_EXTRADATA_MB_ERROR_MAP,
3308                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
3309            }
3310            break;
3311        case OMX_QcomIndexParamFrameInfoExtraData:
3312            {
3313                eRet = enable_extradata(OMX_FRAMEINFO_EXTRADATA,
3314                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
3315            }
3316            break;
3317        case OMX_QcomIndexParamInterlaceExtraData:
3318            {
3319                eRet = enable_extradata(OMX_INTERLACE_EXTRADATA,
3320                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
3321            }
3322            break;
3323        case OMX_QcomIndexParamH264TimeInfo:
3324            {
3325                eRet = enable_extradata(OMX_TIMEINFO_EXTRADATA,
3326                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
3327            }
3328            break;
3329        case OMX_QcomIndexParamVideoDivx:
3330            {
3331#ifdef MAX_RES_720P
3332                QOMX_VIDEO_PARAM_DIVXTYPE* divXType = (QOMX_VIDEO_PARAM_DIVXTYPE *) paramData;
3333
3334                if ((divXType) && (divXType->eFormat == QOMX_VIDEO_DIVXFormat311)) {
3335                    DEBUG_PRINT_HIGH("set_parameter: DivX 3.11 not supported in 7x30 core.");
3336                    eRet = OMX_ErrorUnsupportedSetting;
3337                }
3338
3339#endif
3340            }
3341            break;
3342        case OMX_QcomIndexPlatformPvt:
3343            {
3344                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port");
3345                OMX_QCOM_PLATFORMPRIVATE_EXTN* entryType = (OMX_QCOM_PLATFORMPRIVATE_EXTN *) paramData;
3346
3347                if (entryType->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
3348                    DEBUG_PRINT_HIGH("set_parameter: Platform Private entry type (%d) not supported.", entryType->type);
3349                    eRet = OMX_ErrorUnsupportedSetting;
3350                } else {
3351                    m_out_pvt_entry_pmem = OMX_TRUE;
3352
3353                    if ((m_out_mem_region_smi && m_out_pvt_entry_pmem)) {
3354                        DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexPlatformPvt OP Port: use output pmem set");
3355                        m_use_output_pmem = OMX_TRUE;
3356                    }
3357                }
3358
3359            }
3360            break;
3361        case OMX_QcomIndexParamVideoSyncFrameDecodingMode:
3362            {
3363                DEBUG_PRINT_HIGH("set_parameter: OMX_QcomIndexParamVideoSyncFrameDecodingMode");
3364                DEBUG_PRINT_HIGH("set idr only decoding for thumbnail mode");
3365                drv_ctx.idr_only_decoding = 1;
3366                int rc = ioctl(drv_ctx.video_driver_fd,
3367                        VDEC_IOCTL_SET_IDR_ONLY_DECODING);
3368
3369                if (rc < 0) {
3370                    DEBUG_PRINT_ERROR("Failed to set IDR only decoding on driver.");
3371                    eRet = OMX_ErrorHardware;
3372                }
3373
3374#ifdef MAX_RES_720P
3375
3376                if (eRet == OMX_ErrorNone) {
3377                    DEBUG_PRINT_HIGH("set decode order for thumbnail mode");
3378                    drv_ctx.picture_order = VDEC_ORDER_DECODE;
3379                    ioctl_msg.in = &drv_ctx.picture_order;
3380                    ioctl_msg.out = NULL;
3381
3382                    if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_PICTURE_ORDER,
3383                                (void*)&ioctl_msg) < 0) {
3384                        DEBUG_PRINT_ERROR("\n Set picture order failed");
3385                        eRet = OMX_ErrorUnsupportedSetting;
3386                    }
3387                }
3388
3389#endif
3390            }
3391            break;
3392#ifdef MAX_RES_1080P
3393        case OMX_QcomIndexParamIndexExtraDataType:
3394            {
3395                if (!secure_mode) {
3396                    QOMX_INDEXEXTRADATATYPE *extradataIndexType = (QOMX_INDEXEXTRADATATYPE *) paramData;
3397
3398                    if ((extradataIndexType->nIndex == OMX_IndexParamPortDefinition) &&
3399                            (extradataIndexType->bEnabled == OMX_TRUE) &&
3400                            (extradataIndexType->nPortIndex == 1)) {
3401                        DEBUG_PRINT_HIGH("set_parameter:  OMX_QcomIndexParamIndexExtraDataType SmoothStreaming");
3402                        eRet = enable_extradata(OMX_PORTDEF_EXTRADATA, extradataIndexType->bEnabled);
3403                        // Set smooth streaming parameter
3404                        int rc = ioctl(drv_ctx.video_driver_fd,
3405                                VDEC_IOCTL_SET_CONT_ON_RECONFIG);
3406
3407                        if (rc < 0) {
3408                            DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3409                            eRet = OMX_ErrorHardware;
3410                        }
3411                    }
3412                }
3413            }
3414            break;
3415
3416        case OMX_QcomIndexParamEnableSmoothStreaming:
3417            {
3418
3419                int rc = ioctl(drv_ctx.video_driver_fd,
3420                        VDEC_IOCTL_SET_CONT_ON_RECONFIG);
3421
3422                if (rc < 0) {
3423                    DEBUG_PRINT_ERROR("Failed to enable Smooth Streaming on driver.");
3424                    eRet = OMX_ErrorHardware;
3425                }
3426            }
3427            break;
3428#endif
3429#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3430            /* Need to allow following two set_parameters even in Idle
3431             * state. This is ANDROID architecture which is not in sync
3432             * with openmax standard. */
3433        case OMX_GoogleAndroidIndexEnableAndroidNativeBuffers:
3434            {
3435                EnableAndroidNativeBuffersParams* enableNativeBuffers = (EnableAndroidNativeBuffersParams *) paramData;
3436
3437                if (enableNativeBuffers) {
3438                    m_enable_android_native_buffers = enableNativeBuffers->enable;
3439                }
3440            }
3441            break;
3442        case OMX_GoogleAndroidIndexUseAndroidNativeBuffer:
3443            {
3444                eRet = use_android_native_buffer(hComp, paramData);
3445            }
3446            break;
3447#endif
3448        case OMX_QcomIndexParamEnableTimeStampReorder:
3449            {
3450                QOMX_INDEXTIMESTAMPREORDER *reorder = (QOMX_INDEXTIMESTAMPREORDER *)paramData;
3451
3452                if (drv_ctx.picture_order == QOMX_VIDEO_DISPLAY_ORDER) {
3453                    if (reorder->bEnable == OMX_TRUE) {
3454                        frm_int =0;
3455                        time_stamp_dts.set_timestamp_reorder_mode(true);
3456                    } else
3457                        time_stamp_dts.set_timestamp_reorder_mode(false);
3458                } else {
3459                    time_stamp_dts.set_timestamp_reorder_mode(false);
3460
3461                    if (reorder->bEnable == OMX_TRUE) {
3462                        eRet = OMX_ErrorUnsupportedSetting;
3463                    }
3464                }
3465            }
3466            break;
3467        case OMX_QcomIndexEnableExtnUserData:
3468            {
3469                eRet = enable_extradata(OMX_EXTNUSER_EXTRADATA,
3470                        ((QOMX_ENABLETYPE *)paramData)->bEnable);
3471            }
3472            break;
3473        default:
3474            {
3475                DEBUG_PRINT_ERROR("Setparameter: unknown param %d\n", paramIndex);
3476                eRet = OMX_ErrorUnsupportedIndex;
3477            }
3478    }
3479
3480    return eRet;
3481}
3482
3483/* ======================================================================
3484   FUNCTION
3485   omx_vdec::GetConfig
3486
3487   DESCRIPTION
3488   OMX Get Config Method implementation.
3489
3490   PARAMETERS
3491   <TBD>.
3492
3493   RETURN VALUE
3494   OMX Error None if successful.
3495
3496   ========================================================================== */
3497OMX_ERRORTYPE  omx_vdec::get_config(OMX_IN OMX_HANDLETYPE      hComp,
3498        OMX_IN OMX_INDEXTYPE configIndex,
3499        OMX_INOUT OMX_PTR     configData)
3500{
3501    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3502
3503    if (m_state == OMX_StateInvalid) {
3504        DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3505        return OMX_ErrorInvalidState;
3506    }
3507
3508    switch (configIndex) {
3509        case OMX_QcomIndexConfigInterlaced:
3510            {
3511                OMX_QCOM_CONFIG_INTERLACETYPE *configFmt =
3512                    (OMX_QCOM_CONFIG_INTERLACETYPE *) configData;
3513
3514                if (configFmt->nPortIndex == 1) {
3515                    if (configFmt->nIndex == 0) {
3516                        configFmt->eInterlaceType = OMX_QCOM_InterlaceFrameProgressive;
3517                    } else if (configFmt->nIndex == 1) {
3518                        configFmt->eInterlaceType =
3519                            OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
3520                    } else if (configFmt->nIndex == 2) {
3521                        configFmt->eInterlaceType =
3522                            OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
3523                    } else {
3524                        DEBUG_PRINT_ERROR("get_config: OMX_QcomIndexConfigInterlaced:"
3525                                " NoMore Interlaced formats\n");
3526                        eRet = OMX_ErrorNoMore;
3527                    }
3528
3529                } else {
3530                    DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port\n",
3531                            (int)configFmt->nPortIndex);
3532                    eRet = OMX_ErrorBadPortIndex;
3533                }
3534
3535                break;
3536            }
3537        case OMX_QcomIndexQueryNumberOfVideoDecInstance:
3538            {
3539                struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3540                QOMX_VIDEO_QUERY_DECODER_INSTANCES *decoderinstances =
3541                    (QOMX_VIDEO_QUERY_DECODER_INSTANCES*)configData;
3542                ioctl_msg.out = (void*)&decoderinstances->nNumOfInstances;
3543                (void)(ioctl(drv_ctx.video_driver_fd,
3544                            VDEC_IOCTL_GET_NUMBER_INSTANCES,&ioctl_msg));
3545                break;
3546            }
3547        case OMX_QcomIndexConfigVideoFramePackingArrangement:
3548            {
3549                if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3550                    OMX_QCOM_FRAME_PACK_ARRANGEMENT *configFmt =
3551                        (OMX_QCOM_FRAME_PACK_ARRANGEMENT *) configData;
3552                    h264_parser->get_frame_pack_data(configFmt);
3553                } else {
3554                    DEBUG_PRINT_ERROR("get_config: Framepack data not supported for non H264 codecs");
3555                }
3556
3557                break;
3558            }
3559        case OMX_QcomIndexParamFrameInfoExtraData:
3560            {
3561                OMX_QCOM_EXTRADATA_FRAMEINFO *extradata =
3562                    (OMX_QCOM_EXTRADATA_FRAMEINFO *) configData;
3563
3564                if (m_extradata == NULL) {
3565                    DEBUG_PRINT_LOW("get_config: m_extradata not set. "
3566                            "Aspect Ratio information missing!!");
3567                } else {
3568                    extradata->aspectRatio.aspectRatioX =
3569                        m_extradata->aspectRatio.aspectRatioX;
3570                    extradata->aspectRatio.aspectRatioY =
3571                        m_extradata->aspectRatio.aspectRatioY;
3572                }
3573
3574                break;
3575            }
3576
3577        default:
3578            {
3579                DEBUG_PRINT_ERROR("get_config: unknown param %d\n",configIndex);
3580                eRet = OMX_ErrorBadParameter;
3581            }
3582
3583    }
3584
3585    return eRet;
3586}
3587
3588/* ======================================================================
3589   FUNCTION
3590   omx_vdec::SetConfig
3591
3592   DESCRIPTION
3593   OMX Set Config method implementation
3594
3595   PARAMETERS
3596   <TBD>.
3597
3598   RETURN VALUE
3599   OMX Error None if successful.
3600   ========================================================================== */
3601OMX_ERRORTYPE  omx_vdec::set_config(OMX_IN OMX_HANDLETYPE      hComp,
3602        OMX_IN OMX_INDEXTYPE configIndex,
3603        OMX_IN OMX_PTR        configData)
3604{
3605    if (m_state == OMX_StateInvalid) {
3606        DEBUG_PRINT_ERROR("Get Config in Invalid State\n");
3607        return OMX_ErrorInvalidState;
3608    }
3609
3610    OMX_ERRORTYPE ret = OMX_ErrorNone;
3611    OMX_VIDEO_CONFIG_NALSIZE *pNal;
3612
3613    DEBUG_PRINT_LOW("Set Config Called");
3614
3615    if (m_state == OMX_StateExecuting) {
3616        DEBUG_PRINT_ERROR("set_config:Ignore in Exe state\n");
3617        return ret;
3618    }
3619
3620    if (configIndex == OMX_IndexVendorVideoExtraData) {
3621        OMX_VENDOR_EXTRADATATYPE *config = (OMX_VENDOR_EXTRADATATYPE *) configData;
3622        DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData called");
3623
3624        if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc")) {
3625            DEBUG_PRINT_LOW("Index OMX_IndexVendorVideoExtraData AVC");
3626            OMX_U32 extra_size;
3627            // Parsing done here for the AVC atom is definitely not generic
3628            // Currently this piece of code is working, but certainly
3629            // not tested with all .mp4 files.
3630            // Incase of failure, we might need to revisit this
3631            // for a generic piece of code.
3632
3633            // Retrieve size of NAL length field
3634            // byte #4 contains the size of NAL lenght field
3635            nal_length = (config->pData[4] & 0x03) + 1;
3636
3637            extra_size = 0;
3638
3639            if (nal_length > 2) {
3640                /* Presently we assume that only one SPS and one PPS in AvC1 Atom */
3641                extra_size = (nal_length - 2) * 2;
3642            }
3643
3644            // SPS starts from byte #6
3645            OMX_U8 *pSrcBuf = (OMX_U8 *) (&config->pData[6]);
3646            OMX_U8 *pDestBuf;
3647            m_vendor_config.nPortIndex = config->nPortIndex;
3648
3649            // minus 6 --> SPS starts from byte #6
3650            // minus 1 --> picture param set byte to be ignored from avcatom
3651            m_vendor_config.nDataSize = config->nDataSize - 6 - 1 + extra_size;
3652            m_vendor_config.pData = (OMX_U8 *) malloc(m_vendor_config.nDataSize);
3653            OMX_U32 len;
3654            OMX_U8 index = 0;
3655            // case where SPS+PPS is sent as part of set_config
3656            pDestBuf = m_vendor_config.pData;
3657
3658            DEBUG_PRINT_LOW("Rxd SPS+PPS nPortIndex[%d] len[%d] data[0x%x]",
3659                    m_vendor_config.nPortIndex,
3660                    m_vendor_config.nDataSize,
3661                    m_vendor_config.pData);
3662
3663            while (index < 2) {
3664                uint8 *psize;
3665                len = *pSrcBuf;
3666                len = len << 8;
3667                len |= *(pSrcBuf + 1);
3668                psize = (uint8 *) & len;
3669                memcpy(pDestBuf + nal_length, pSrcBuf + 2,len);
3670
3671                for (int i = 0; i < nal_length; i++) {
3672                    pDestBuf[i] = psize[nal_length - 1 - i];
3673                }
3674
3675                //memcpy(pDestBuf,pSrcBuf,(len+2));
3676                pDestBuf += len + nal_length;
3677                pSrcBuf += len + 2;
3678                index++;
3679                pSrcBuf++;   // skip picture param set
3680                len = 0;
3681            }
3682        } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4") ||
3683                !strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2")) {
3684            m_vendor_config.nPortIndex = config->nPortIndex;
3685            m_vendor_config.nDataSize = config->nDataSize;
3686            m_vendor_config.pData = (OMX_U8 *) malloc((config->nDataSize));
3687            memcpy(m_vendor_config.pData, config->pData,config->nDataSize);
3688        } else if (!strcmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1")) {
3689            if (m_vendor_config.pData) {
3690                free(m_vendor_config.pData);
3691                m_vendor_config.pData = NULL;
3692                m_vendor_config.nDataSize = 0;
3693            }
3694
3695            if (((*((OMX_U32 *) config->pData)) &
3696                        VC1_SP_MP_START_CODE_MASK) ==
3697                    VC1_SP_MP_START_CODE) {
3698                DEBUG_PRINT_LOW("set_config - VC1 simple/main profile\n");
3699                m_vendor_config.nPortIndex = config->nPortIndex;
3700                m_vendor_config.nDataSize = config->nDataSize;
3701                m_vendor_config.pData =
3702                    (OMX_U8 *) malloc(config->nDataSize);
3703                memcpy(m_vendor_config.pData, config->pData,
3704                        config->nDataSize);
3705                m_vc1_profile = VC1_SP_MP_RCV;
3706            } else if (*((OMX_U32 *) config->pData) == VC1_AP_SEQ_START_CODE) {
3707                DEBUG_PRINT_LOW("set_config - VC1 Advance profile\n");
3708                m_vendor_config.nPortIndex = config->nPortIndex;
3709                m_vendor_config.nDataSize = config->nDataSize;
3710                m_vendor_config.pData =
3711                    (OMX_U8 *) malloc((config->nDataSize));
3712                memcpy(m_vendor_config.pData, config->pData,
3713                        config->nDataSize);
3714                m_vc1_profile = VC1_AP;
3715            } else if ((config->nDataSize == VC1_STRUCT_C_LEN)) {
3716                DEBUG_PRINT_LOW("set_config - VC1 Simple/Main profile struct C only\n");
3717                m_vendor_config.nPortIndex = config->nPortIndex;
3718                m_vendor_config.nDataSize  = config->nDataSize;
3719                m_vendor_config.pData = (OMX_U8*)malloc(config->nDataSize);
3720                memcpy(m_vendor_config.pData,config->pData,config->nDataSize);
3721                m_vc1_profile = VC1_SP_MP_RCV;
3722            } else {
3723                DEBUG_PRINT_LOW("set_config - Error: Unknown VC1 profile\n");
3724            }
3725        }
3726
3727        return ret;
3728    } else if (configIndex == OMX_IndexConfigVideoNalSize) {
3729
3730        pNal = reinterpret_cast < OMX_VIDEO_CONFIG_NALSIZE * >(configData);
3731        nal_length = pNal->nNaluBytes;
3732        m_frame_parser.init_nal_length(nal_length);
3733        DEBUG_PRINT_LOW("OMX_IndexConfigVideoNalSize called with Size %d",nal_length);
3734        return ret;
3735    }
3736
3737    return OMX_ErrorNotImplemented;
3738}
3739
3740/* ======================================================================
3741   FUNCTION
3742   omx_vdec::GetExtensionIndex
3743
3744   DESCRIPTION
3745   OMX GetExtensionIndex method implementaion.  <TBD>
3746
3747   PARAMETERS
3748   <TBD>.
3749
3750   RETURN VALUE
3751   OMX Error None if everything successful.
3752
3753   ========================================================================== */
3754OMX_ERRORTYPE  omx_vdec::get_extension_index(OMX_IN OMX_HANDLETYPE      hComp,
3755        OMX_IN OMX_STRING      paramName,
3756        OMX_OUT OMX_INDEXTYPE* indexType)
3757{
3758    if (m_state == OMX_StateInvalid) {
3759        DEBUG_PRINT_ERROR("Get Extension Index in Invalid State\n");
3760        return OMX_ErrorInvalidState;
3761    } else if (!strncmp(paramName, "OMX.QCOM.index.param.video.SyncFrameDecodingMode",sizeof("OMX.QCOM.index.param.video.SyncFrameDecodingMode") - 1)) {
3762        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoSyncFrameDecodingMode;
3763    }
3764
3765#ifdef MAX_RES_1080P
3766    else if (!strncmp(paramName, "OMX.QCOM.index.param.IndexExtraData",sizeof("OMX.QCOM.index.param.IndexExtraData") - 1)) {
3767        *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamIndexExtraDataType;
3768    }
3769
3770#endif
3771#if defined (_ANDROID_HONEYCOMB_) || defined (_ANDROID_ICS_)
3772    else if (!strncmp(paramName,"OMX.google.android.index.enableAndroidNativeBuffers", sizeof("OMX.google.android.index.enableAndroidNativeBuffers") - 1)) {
3773        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexEnableAndroidNativeBuffers;
3774    } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer2", sizeof("OMX.google.android.index.enableAndroidNativeBuffer2") - 1)) {
3775        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer2;
3776    } else if (!strncmp(paramName,"OMX.google.android.index.useAndroidNativeBuffer", sizeof("OMX.google.android.index.enableAndroidNativeBuffer") - 1)) {
3777        DEBUG_PRINT_ERROR("Extension: %s is supported\n", paramName);
3778        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexUseAndroidNativeBuffer;
3779    } else if (!strncmp(paramName,"OMX.google.android.index.getAndroidNativeBufferUsage", sizeof("OMX.google.android.index.getAndroidNativeBufferUsage") - 1)) {
3780        *indexType = (OMX_INDEXTYPE)OMX_GoogleAndroidIndexGetAndroidNativeBufferUsage;
3781    }
3782
3783#endif
3784    else {
3785        DEBUG_PRINT_ERROR("Extension: %s not implemented\n", paramName);
3786        return OMX_ErrorNotImplemented;
3787    }
3788
3789    return OMX_ErrorNone;
3790}
3791
3792/* ======================================================================
3793   FUNCTION
3794   omx_vdec::GetState
3795
3796   DESCRIPTION
3797   Returns the state information back to the caller.<TBD>
3798
3799   PARAMETERS
3800   <TBD>.
3801
3802   RETURN VALUE
3803   Error None if everything is successful.
3804   ========================================================================== */
3805OMX_ERRORTYPE  omx_vdec::get_state(OMX_IN OMX_HANDLETYPE  hComp,
3806        OMX_OUT OMX_STATETYPE* state)
3807{
3808    *state = m_state;
3809    DEBUG_PRINT_LOW("get_state: Returning the state %d",*state);
3810    return OMX_ErrorNone;
3811}
3812
3813/* ======================================================================
3814   FUNCTION
3815   omx_vdec::ComponentTunnelRequest
3816
3817   DESCRIPTION
3818   OMX Component Tunnel Request method implementation. <TBD>
3819
3820   PARAMETERS
3821   None.
3822
3823   RETURN VALUE
3824   OMX Error None if everything successful.
3825
3826   ========================================================================== */
3827OMX_ERRORTYPE  omx_vdec::component_tunnel_request(OMX_IN OMX_HANDLETYPE                hComp,
3828        OMX_IN OMX_U32                        port,
3829        OMX_IN OMX_HANDLETYPE        peerComponent,
3830        OMX_IN OMX_U32                    peerPort,
3831        OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
3832{
3833    DEBUG_PRINT_ERROR("Error: component_tunnel_request Not Implemented\n");
3834    return OMX_ErrorNotImplemented;
3835}
3836
3837/* ======================================================================
3838   FUNCTION
3839   omx_vdec::UseOutputBuffer
3840
3841   DESCRIPTION
3842   Helper function for Use buffer in the input pin
3843
3844   PARAMETERS
3845   None.
3846
3847   RETURN VALUE
3848   true/false
3849
3850   ========================================================================== */
3851OMX_ERRORTYPE  omx_vdec::use_output_buffer(
3852        OMX_IN OMX_HANDLETYPE            hComp,
3853        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3854        OMX_IN OMX_U32                   port,
3855        OMX_IN OMX_PTR                   appData,
3856        OMX_IN OMX_U32                   bytes,
3857        OMX_IN OMX_U8*                   buffer)
3858{
3859    OMX_ERRORTYPE eRet = OMX_ErrorNone;
3860    OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
3861    unsigned                         i= 0; // Temporary counter
3862    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
3863    struct vdec_setbuffer_cmd setbuffers;
3864    OMX_PTR privateAppData = NULL;
3865#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
3866    private_handle_t *handle = NULL;
3867#endif
3868    OMX_U8 *buff = buffer;
3869
3870    if (!m_out_mem_ptr) {
3871        DEBUG_PRINT_HIGH("Use_op_buf:Allocating output headers");
3872        eRet = allocate_output_headers();
3873
3874#ifdef MAX_RES_1080P
3875
3876        if (secure_mode) {
3877            eRet = vdec_alloc_meta_buffers();
3878
3879            if (eRet) {
3880                DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n");
3881                return OMX_ErrorInsufficientResources;
3882            }
3883        }
3884
3885        if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
3886            //allocate H264_mv_buffer
3887            eRet = vdec_alloc_h264_mv();
3888
3889            if (eRet) {
3890                DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n");
3891                return OMX_ErrorInsufficientResources;
3892            }
3893        }
3894
3895#endif
3896
3897    }
3898
3899    if (eRet == OMX_ErrorNone) {
3900        for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
3901            if (BITMASK_ABSENT(&m_out_bm_count,i)) {
3902                break;
3903            }
3904        }
3905    }
3906
3907    if (i >= drv_ctx.op_buf.actualcount) {
3908        eRet = OMX_ErrorInsufficientResources;
3909    }
3910
3911    if (eRet == OMX_ErrorNone) {
3912#if defined(_ANDROID_HONEYCOMB_) || defined(_ANDROID_ICS_)
3913
3914        if (m_enable_android_native_buffers) {
3915            if (m_use_android_native_buffers) {
3916                UseAndroidNativeBufferParams *params = (UseAndroidNativeBufferParams *)appData;
3917                sp<android_native_buffer_t> nBuf = params->nativeBuffer;
3918                handle = (private_handle_t *)nBuf->handle;
3919                privateAppData = params->pAppPrivate;
3920            } else {
3921                handle = (private_handle_t *)buff;
3922                privateAppData = appData;
3923            }
3924
3925            if ((OMX_U32)handle->size < drv_ctx.op_buf.buffer_size) {
3926                DEBUG_PRINT_ERROR("Insufficient sized buffer given for playback,"
3927                        " expected %u, got %lu",
3928                        drv_ctx.op_buf.buffer_size, (OMX_U32)handle->size);
3929                return OMX_ErrorBadParameter;
3930            }
3931
3932            if (!m_use_android_native_buffers) {
3933                if (!secure_mode) {
3934                    buff =  (OMX_U8*)mmap(0, handle->size,
3935                            PROT_READ|PROT_WRITE, MAP_SHARED, handle->fd, 0);
3936
3937                    if (buff == MAP_FAILED) {
3938                        DEBUG_PRINT_ERROR("Failed to mmap pmem with fd = %d, size = %d", handle->fd, handle->size);
3939                        return OMX_ErrorInsufficientResources;
3940                    }
3941                }
3942            }
3943
3944#if defined(_ANDROID_ICS_)
3945            native_buffer[i].nativehandle = handle;
3946#endif
3947
3948            if (!handle) {
3949                DEBUG_PRINT_ERROR("Native Buffer handle is NULL");
3950                return OMX_ErrorBadParameter;
3951            }
3952
3953            drv_ctx.ptr_outputbuffer[i].pmem_fd = handle->fd;
3954            drv_ctx.ptr_outputbuffer[i].offset = 0;
3955            drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
3956            drv_ctx.ptr_outputbuffer[i].mmaped_size =
3957                drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
3958#if defined(_ANDROID_ICS_)
3959
3960            if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) {
3961                int enable = 1;
3962                setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable);
3963            }
3964
3965#endif
3966        } else
3967#endif
3968
3969            if (!ouput_egl_buffers && !m_use_output_pmem) {
3970#ifdef USE_ION
3971                drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
3972                        drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
3973                        &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
3974                        &drv_ctx.op_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED);
3975
3976                if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
3977                    return OMX_ErrorInsufficientResources;
3978                }
3979
3980                drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3981                                                      drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
3982#else
3983                drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3984                                                      open (MEM_DEVICE,O_RDWR);
3985
3986                if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3987                    return OMX_ErrorInsufficientResources;
3988                }
3989
3990                if (drv_ctx.ptr_outputbuffer[i].pmem_fd == 0) {
3991                    drv_ctx.ptr_outputbuffer[i].pmem_fd = \
3992                                                          open (MEM_DEVICE,O_RDWR);
3993
3994                    if (drv_ctx.ptr_outputbuffer[i].pmem_fd < 0) {
3995                        return OMX_ErrorInsufficientResources;
3996                    }
3997                }
3998
3999                if (!align_pmem_buffers(drv_ctx.ptr_outputbuffer[i].pmem_fd,
4000                            drv_ctx.op_buf.buffer_size,
4001                            drv_ctx.op_buf.alignment)) {
4002                    DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4003                    close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4004                    return OMX_ErrorInsufficientResources;
4005                }
4006
4007#endif
4008
4009                if (!secure_mode) {
4010                    drv_ctx.ptr_outputbuffer[i].bufferaddr =
4011                        (unsigned char *)mmap(NULL, drv_ctx.op_buf.buffer_size,
4012                                PROT_READ|PROT_WRITE, MAP_SHARED,
4013                                drv_ctx.ptr_outputbuffer[i].pmem_fd,0);
4014
4015                    if (drv_ctx.ptr_outputbuffer[i].bufferaddr == MAP_FAILED) {
4016                        close(drv_ctx.ptr_outputbuffer[i].pmem_fd);
4017#ifdef USE_ION
4018                        free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4019#endif
4020                        return OMX_ErrorInsufficientResources;
4021                    }
4022                }
4023
4024                drv_ctx.ptr_outputbuffer[i].offset = 0;
4025                privateAppData = appData;
4026            } else {
4027
4028                DEBUG_PRINT_LOW("Use_op_buf: out_pmem=%d",m_use_output_pmem);
4029
4030                if (!appData || !bytes ) {
4031                    DEBUG_PRINT_ERROR("\n Invalid appData or bytes");
4032                    return OMX_ErrorBadParameter;
4033                }
4034
4035                if (!secure_mode && !buffer) {
4036                    DEBUG_PRINT_ERROR("\n Bad parameters for use buffer in EGL image case");
4037                    return OMX_ErrorBadParameter;
4038                }
4039
4040
4041                OMX_QCOM_PLATFORM_PRIVATE_LIST *pmem_list;
4042                OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pmem_info;
4043                pmem_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST*) appData;
4044
4045                if (!pmem_list->entryList || !pmem_list->entryList->entry ||
4046                        !pmem_list->nEntries ||
4047                        pmem_list->entryList->type != OMX_QCOM_PLATFORM_PRIVATE_PMEM) {
4048                    DEBUG_PRINT_ERROR("\n Pmem info not valid in use buffer");
4049                    return OMX_ErrorBadParameter;
4050                }
4051
4052                pmem_info = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4053                    pmem_list->entryList->entry;
4054                DEBUG_PRINT_LOW("vdec: use buf: pmem_fd=0x%x",
4055                        pmem_info->pmem_fd);
4056                drv_ctx.ptr_outputbuffer[i].pmem_fd = pmem_info->pmem_fd;
4057                drv_ctx.ptr_outputbuffer[i].offset = pmem_info->offset;
4058                drv_ctx.ptr_outputbuffer[i].bufferaddr = buff;
4059                drv_ctx.ptr_outputbuffer[i].mmaped_size =
4060                    drv_ctx.ptr_outputbuffer[i].buffer_len = drv_ctx.op_buf.buffer_size;
4061                privateAppData = appData;
4062            }
4063
4064        m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4065        m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd;
4066
4067        *bufferHdr = (m_out_mem_ptr + i );
4068
4069        if (secure_mode)
4070            drv_ctx.ptr_outputbuffer[i].bufferaddr = *bufferHdr;
4071
4072        setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4073        memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[i],
4074                sizeof (vdec_bufferpayload));
4075
4076        ioctl_msg.in  = &setbuffers;
4077        ioctl_msg.out = NULL;
4078
4079        DEBUG_PRINT_HIGH("Set the Output Buffer Idx: %d Addr: %x, pmem_fd=%0x%x", i,
4080                drv_ctx.ptr_outputbuffer[i],drv_ctx.ptr_outputbuffer[i].pmem_fd );
4081
4082        if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4083                    &ioctl_msg) < 0) {
4084            DEBUG_PRINT_ERROR("\n Set output buffer failed");
4085            return OMX_ErrorInsufficientResources;
4086        }
4087
4088        // found an empty buffer at i
4089        (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
4090
4091        if (m_enable_android_native_buffers) {
4092            DEBUG_PRINT_LOW("setting pBuffer to private_handle_t %p", handle);
4093            (*bufferHdr)->pBuffer = (OMX_U8 *)handle;
4094        } else {
4095            (*bufferHdr)->pBuffer = buff;
4096        }
4097
4098        (*bufferHdr)->pAppPrivate = privateAppData;
4099        BITMASK_SET(&m_out_bm_count,i);
4100    }
4101
4102    return eRet;
4103}
4104
4105/* ======================================================================
4106   FUNCTION
4107   omx_vdec::use_input_heap_buffers
4108
4109   DESCRIPTION
4110   OMX Use Buffer Heap allocation method implementation.
4111
4112   PARAMETERS
4113   <TBD>.
4114
4115   RETURN VALUE
4116   OMX Error None , if everything successful.
4117
4118   ========================================================================== */
4119OMX_ERRORTYPE  omx_vdec::use_input_heap_buffers(
4120        OMX_IN OMX_HANDLETYPE            hComp,
4121        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4122        OMX_IN OMX_U32                   port,
4123        OMX_IN OMX_PTR                   appData,
4124        OMX_IN OMX_U32                   bytes,
4125        OMX_IN OMX_U8*                   buffer)
4126{
4127    DEBUG_PRINT_LOW("Inside %s, %p", __FUNCTION__, buffer);
4128    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4129
4130    if (!m_inp_heap_ptr)
4131        m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*)
4132            calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4133                    drv_ctx.ip_buf.actualcount);
4134
4135    if (!m_phdr_pmem_ptr)
4136        m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**)
4137            calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4138                    drv_ctx.ip_buf.actualcount);
4139
4140    if (!m_inp_heap_ptr || !m_phdr_pmem_ptr) {
4141        DEBUG_PRINT_ERROR("Insufficent memory");
4142        eRet = OMX_ErrorInsufficientResources;
4143    } else if (m_in_alloc_cnt < drv_ctx.ip_buf.actualcount) {
4144        input_use_buffer = true;
4145        memset(&m_inp_heap_ptr[m_in_alloc_cnt], 0, sizeof(OMX_BUFFERHEADERTYPE));
4146        m_inp_heap_ptr[m_in_alloc_cnt].pBuffer = buffer;
4147        m_inp_heap_ptr[m_in_alloc_cnt].nAllocLen = bytes;
4148        m_inp_heap_ptr[m_in_alloc_cnt].pAppPrivate = appData;
4149        m_inp_heap_ptr[m_in_alloc_cnt].nInputPortIndex = (OMX_U32) OMX_DirInput;
4150        m_inp_heap_ptr[m_in_alloc_cnt].nOutputPortIndex = (OMX_U32) OMX_DirMax;
4151        *bufferHdr = &m_inp_heap_ptr[m_in_alloc_cnt];
4152        eRet = allocate_input_buffer(hComp, &m_phdr_pmem_ptr[m_in_alloc_cnt], port, appData, bytes);
4153        DEBUG_PRINT_HIGH("Heap buffer(%p) Pmem buffer(%p)", *bufferHdr, m_phdr_pmem_ptr[m_in_alloc_cnt]);
4154
4155        if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr[m_in_alloc_cnt], NULL, NULL)) {
4156            DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4157            return OMX_ErrorInsufficientResources;
4158        }
4159
4160        m_in_alloc_cnt++;
4161    } else {
4162        DEBUG_PRINT_ERROR("All i/p buffers have been set!");
4163        eRet = OMX_ErrorInsufficientResources;
4164    }
4165
4166    return eRet;
4167}
4168
4169/* ======================================================================
4170   FUNCTION
4171   omx_vdec::UseBuffer
4172
4173   DESCRIPTION
4174   OMX Use Buffer method implementation.
4175
4176   PARAMETERS
4177   <TBD>.
4178
4179   RETURN VALUE
4180   OMX Error None , if everything successful.
4181
4182   ========================================================================== */
4183OMX_ERRORTYPE  omx_vdec::use_buffer(
4184        OMX_IN OMX_HANDLETYPE            hComp,
4185        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4186        OMX_IN OMX_U32                   port,
4187        OMX_IN OMX_PTR                   appData,
4188        OMX_IN OMX_U32                   bytes,
4189        OMX_IN OMX_U8*                   buffer)
4190{
4191    OMX_ERRORTYPE error = OMX_ErrorNone;
4192    struct vdec_setbuffer_cmd setbuffers;
4193    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4194
4195    if (bufferHdr == NULL || bytes == 0) {
4196        DEBUG_PRINT_ERROR("bad param 0x%p %ld",bufferHdr, bytes);
4197        return OMX_ErrorBadParameter;
4198    }
4199
4200    if (!secure_mode && buffer == NULL) {
4201        DEBUG_PRINT_ERROR("bad param 0x%p",buffer);
4202        return OMX_ErrorBadParameter;
4203    }
4204
4205    if (m_state == OMX_StateInvalid) {
4206        DEBUG_PRINT_ERROR("Use Buffer in Invalid State\n");
4207        return OMX_ErrorInvalidState;
4208    }
4209
4210    if (port == OMX_CORE_INPUT_PORT_INDEX)
4211        error = use_input_heap_buffers(hComp, bufferHdr, port, appData, bytes, buffer);
4212    else if (port == OMX_CORE_OUTPUT_PORT_INDEX)
4213        error = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer); //not tested
4214    else {
4215        DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
4216        error = OMX_ErrorBadPortIndex;
4217    }
4218
4219    DEBUG_PRINT_LOW("Use Buffer: port %u, buffer %p, eRet %d", port, *bufferHdr, error);
4220
4221    if (error == OMX_ErrorNone) {
4222        if (allocate_done() && BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
4223            // Send the callback now
4224            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
4225            post_event(OMX_CommandStateSet,OMX_StateIdle,
4226                    OMX_COMPONENT_GENERATE_EVENT);
4227        }
4228
4229        if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated &&
4230                BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
4231            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
4232            post_event(OMX_CommandPortEnable,
4233                    OMX_CORE_INPUT_PORT_INDEX,
4234                    OMX_COMPONENT_GENERATE_EVENT);
4235        } else if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated &&
4236                BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
4237            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
4238            post_event(OMX_CommandPortEnable,
4239                    OMX_CORE_OUTPUT_PORT_INDEX,
4240                    OMX_COMPONENT_GENERATE_EVENT);
4241        }
4242    }
4243
4244    return error;
4245}
4246
4247OMX_ERRORTYPE omx_vdec::free_input_buffer(unsigned int bufferindex,
4248        OMX_BUFFERHEADERTYPE *pmem_bufferHdr)
4249{
4250    if (m_inp_heap_ptr && !input_use_buffer && arbitrary_bytes) {
4251        if (m_inp_heap_ptr[bufferindex].pBuffer)
4252            free(m_inp_heap_ptr[bufferindex].pBuffer);
4253
4254        m_inp_heap_ptr[bufferindex].pBuffer = NULL;
4255    }
4256
4257    if (pmem_bufferHdr)
4258        free_input_buffer(pmem_bufferHdr);
4259
4260    return OMX_ErrorNone;
4261}
4262
4263OMX_ERRORTYPE omx_vdec::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4264{
4265    unsigned int index = 0;
4266
4267    if (bufferHdr == NULL || m_inp_mem_ptr == NULL) {
4268        return OMX_ErrorBadParameter;
4269    }
4270
4271    index = bufferHdr - m_inp_mem_ptr;
4272    DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
4273
4274    if (index < drv_ctx.ip_buf.actualcount && drv_ctx.ptr_inputbuffer) {
4275        DEBUG_PRINT_LOW("Free Input Buffer index = %d",index);
4276
4277        if (drv_ctx.ptr_inputbuffer[index].pmem_fd > 0) {
4278            struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4279            struct vdec_setbuffer_cmd setbuffers;
4280            setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4281            memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer[index],
4282                    sizeof (vdec_bufferpayload));
4283            ioctl_msg.in  = &setbuffers;
4284            ioctl_msg.out = NULL;
4285            int ioctl_r = ioctl (drv_ctx.video_driver_fd,
4286                    VDEC_IOCTL_FREE_BUFFER, &ioctl_msg);
4287
4288            if (ioctl_r < 0) {
4289                DEBUG_PRINT_ERROR("\nVDEC_IOCTL_FREE_BUFFER returned error %d", ioctl_r);
4290            }
4291
4292            if (!secure_mode) {
4293                DEBUG_PRINT_LOW("unmap the input buffer fd=%d",
4294                        drv_ctx.ptr_inputbuffer[index].pmem_fd);
4295                DEBUG_PRINT_LOW("unmap the input buffer size=%d  address = %d",
4296                        drv_ctx.ptr_inputbuffer[index].mmaped_size,
4297                        drv_ctx.ptr_inputbuffer[index].bufferaddr);
4298                munmap (drv_ctx.ptr_inputbuffer[index].bufferaddr,
4299                        drv_ctx.ptr_inputbuffer[index].mmaped_size);
4300            }
4301
4302            close (drv_ctx.ptr_inputbuffer[index].pmem_fd);
4303            drv_ctx.ptr_inputbuffer[index].pmem_fd = -1;
4304
4305            if (m_desc_buffer_ptr && m_desc_buffer_ptr[index].buf_addr) {
4306                free(m_desc_buffer_ptr[index].buf_addr);
4307                m_desc_buffer_ptr[index].buf_addr = NULL;
4308                m_desc_buffer_ptr[index].desc_data_size = 0;
4309            }
4310
4311#ifdef USE_ION
4312            free_ion_memory(&drv_ctx.ip_buf_ion_info[index]);
4313#endif
4314        }
4315    }
4316
4317    return OMX_ErrorNone;
4318}
4319
4320OMX_ERRORTYPE omx_vdec::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
4321{
4322    unsigned int index = 0;
4323
4324    if (bufferHdr == NULL || m_out_mem_ptr == NULL) {
4325        DEBUG_PRINT_ERROR("\nfree_output_buffer ERROR");
4326        return OMX_ErrorBadParameter;
4327    }
4328
4329    index = bufferHdr - m_out_mem_ptr;
4330    DEBUG_PRINT_LOW("Free ouput Buffer index = %d",index);
4331
4332    if (index < drv_ctx.op_buf.actualcount
4333            && drv_ctx.ptr_outputbuffer) {
4334        DEBUG_PRINT_LOW("Free ouput Buffer index = %d addr = %x", index,
4335                drv_ctx.ptr_outputbuffer[index].bufferaddr);
4336
4337        struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4338        struct vdec_setbuffer_cmd setbuffers;
4339        setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4340        memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer[index],
4341                sizeof (vdec_bufferpayload));
4342        ioctl_msg.in  = &setbuffers;
4343        ioctl_msg.out = NULL;
4344        DEBUG_PRINT_LOW("Release the Output Buffer");
4345
4346        if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_BUFFER,
4347                    &ioctl_msg) < 0)
4348            DEBUG_PRINT_ERROR("\n Release output buffer failed in VCD");
4349
4350#ifdef _ANDROID_
4351
4352        if (m_enable_android_native_buffers) {
4353            if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0) {
4354                if (!secure_mode) {
4355                    munmap(drv_ctx.ptr_outputbuffer[index].bufferaddr,
4356                            drv_ctx.ptr_outputbuffer[index].mmaped_size);
4357                }
4358            }
4359
4360            drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4361        } else {
4362#endif
4363
4364            if (drv_ctx.ptr_outputbuffer[index].pmem_fd > 0 && !ouput_egl_buffers && !m_use_output_pmem) {
4365                if (!secure_mode) {
4366                    DEBUG_PRINT_LOW("unmap the output buffer fd = %d",
4367                            drv_ctx.ptr_outputbuffer[index].pmem_fd);
4368                    DEBUG_PRINT_LOW("unmap the ouput buffer size=%d  address = %d",
4369                            drv_ctx.ptr_outputbuffer[index].mmaped_size,
4370                            drv_ctx.ptr_outputbuffer[index].bufferaddr);
4371                    munmap (drv_ctx.ptr_outputbuffer[index].bufferaddr,
4372                            drv_ctx.ptr_outputbuffer[index].mmaped_size);
4373                }
4374
4375                close (drv_ctx.ptr_outputbuffer[index].pmem_fd);
4376                drv_ctx.ptr_outputbuffer[index].pmem_fd = -1;
4377#ifdef USE_ION
4378                free_ion_memory(&drv_ctx.op_buf_ion_info[index]);
4379#endif
4380#ifdef _ANDROID_
4381                m_heap_ptr[index].video_heap_ptr = NULL;
4382                m_heap_count = m_heap_count - 1;
4383
4384                if (m_heap_count == 0) {
4385                    free(m_heap_ptr);
4386                    m_heap_ptr = NULL;
4387                }
4388
4389#endif // _ANDROID_
4390            }
4391
4392#ifdef _ANDROID_
4393        }
4394
4395#endif
4396    }
4397
4398#ifdef MAX_RES_1080P
4399
4400    if (secure_mode) {
4401        vdec_dealloc_meta_buffers();
4402    }
4403
4404    if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
4405        vdec_dealloc_h264_mv();
4406    }
4407
4408#endif
4409
4410    return OMX_ErrorNone;
4411
4412}
4413
4414OMX_ERRORTYPE omx_vdec::allocate_input_heap_buffer(OMX_HANDLETYPE       hComp,
4415        OMX_BUFFERHEADERTYPE **bufferHdr,
4416        OMX_U32              port,
4417        OMX_PTR              appData,
4418        OMX_U32              bytes)
4419{
4420    OMX_BUFFERHEADERTYPE *input = NULL;
4421    unsigned char *buf_addr = NULL;
4422    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4423    unsigned   i = 0;
4424
4425    /* Sanity Check*/
4426    if (bufferHdr == NULL) {
4427        return OMX_ErrorBadParameter;
4428    }
4429
4430    if (m_inp_heap_ptr == NULL) {
4431        m_inp_heap_ptr = (OMX_BUFFERHEADERTYPE*) \
4432                         calloc( (sizeof(OMX_BUFFERHEADERTYPE)),
4433                                 drv_ctx.ip_buf.actualcount);
4434        m_phdr_pmem_ptr = (OMX_BUFFERHEADERTYPE**) \
4435                          calloc( (sizeof(OMX_BUFFERHEADERTYPE*)),
4436                                  drv_ctx.ip_buf.actualcount);
4437
4438        if (m_inp_heap_ptr == NULL) {
4439            DEBUG_PRINT_ERROR("\n m_inp_heap_ptr Allocation failed ");
4440            return OMX_ErrorInsufficientResources;
4441        }
4442    }
4443
4444    /*Find a Free index*/
4445    for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4446        if (BITMASK_ABSENT(&m_heap_inp_bm_count,i)) {
4447            DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
4448            break;
4449        }
4450    }
4451
4452    if (i < drv_ctx.ip_buf.actualcount) {
4453        buf_addr = (unsigned char *)malloc (drv_ctx.ip_buf.buffer_size);
4454
4455        if (buf_addr == NULL) {
4456            return OMX_ErrorInsufficientResources;
4457        }
4458
4459        *bufferHdr = (m_inp_heap_ptr + i);
4460        input = *bufferHdr;
4461        BITMASK_SET(&m_heap_inp_bm_count,i);
4462
4463        input->pBuffer           = (OMX_U8 *)buf_addr;
4464        input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
4465        input->nVersion.nVersion = OMX_SPEC_VERSION;
4466        input->nAllocLen         = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH;
4467        input->pAppPrivate       = appData;
4468        input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
4469        DEBUG_PRINT_LOW("Address of Heap Buffer %p",*bufferHdr );
4470        eRet = allocate_input_buffer(hComp,&m_phdr_pmem_ptr [i],port,appData,bytes);
4471        DEBUG_PRINT_LOW("Address of Pmem Buffer %p",m_phdr_pmem_ptr [i] );
4472
4473        /*Add the Buffers to freeq*/
4474        if (!m_input_free_q.insert_entry((unsigned)m_phdr_pmem_ptr [i],NULL,NULL)) {
4475            DEBUG_PRINT_ERROR("\nERROR:Free_q is full");
4476            return OMX_ErrorInsufficientResources;
4477        }
4478    } else {
4479        return OMX_ErrorBadParameter;
4480    }
4481
4482    return eRet;
4483
4484}
4485
4486
4487/* ======================================================================
4488   FUNCTION
4489   omx_vdec::AllocateInputBuffer
4490
4491   DESCRIPTION
4492   Helper function for allocate buffer in the input pin
4493
4494   PARAMETERS
4495   None.
4496
4497   RETURN VALUE
4498   true/false
4499
4500   ========================================================================== */
4501OMX_ERRORTYPE  omx_vdec::allocate_input_buffer(
4502        OMX_IN OMX_HANDLETYPE            hComp,
4503        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4504        OMX_IN OMX_U32                   port,
4505        OMX_IN OMX_PTR                   appData,
4506        OMX_IN OMX_U32                   bytes)
4507{
4508
4509    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4510    struct vdec_setbuffer_cmd setbuffers;
4511    OMX_BUFFERHEADERTYPE *input = NULL;
4512    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4513    unsigned   i = 0;
4514    unsigned char *buf_addr = NULL;
4515    int pmem_fd = -1;
4516
4517    if ((bytes + DEVICE_SCRATCH) != drv_ctx.ip_buf.buffer_size) {
4518        DEBUG_PRINT_LOW("Requested Size is wrong %d epected is %d",
4519                bytes, drv_ctx.ip_buf.buffer_size);
4520        //return OMX_ErrorBadParameter;
4521    }
4522
4523    if (!m_inp_mem_ptr) {
4524        DEBUG_PRINT_HIGH("Allocate i/p buffer Header: Cnt(%d) Sz(%d)",
4525                drv_ctx.ip_buf.actualcount,
4526                drv_ctx.ip_buf.buffer_size);
4527
4528        m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
4529                        calloc( (sizeof(OMX_BUFFERHEADERTYPE)), drv_ctx.ip_buf.actualcount);
4530
4531        if (m_inp_mem_ptr == NULL) {
4532            return OMX_ErrorInsufficientResources;
4533        }
4534
4535        drv_ctx.ptr_inputbuffer = (struct vdec_bufferpayload *) \
4536                                  calloc ((sizeof (struct vdec_bufferpayload)),drv_ctx.ip_buf.actualcount);
4537
4538        if (drv_ctx.ptr_inputbuffer == NULL) {
4539            return OMX_ErrorInsufficientResources;
4540        }
4541
4542#ifdef USE_ION
4543        drv_ctx.ip_buf_ion_info = (struct vdec_ion *) \
4544                                  calloc ((sizeof (struct vdec_ion)),drv_ctx.ip_buf.actualcount);
4545
4546        if (drv_ctx.ip_buf_ion_info == NULL) {
4547            return OMX_ErrorInsufficientResources;
4548        }
4549
4550#endif
4551
4552        for (i=0; i < drv_ctx.ip_buf.actualcount; i++) {
4553            drv_ctx.ptr_inputbuffer [i].pmem_fd = -1;
4554#ifdef USE_ION
4555            drv_ctx.ip_buf_ion_info[i].ion_device_fd = -1;
4556#endif
4557        }
4558    }
4559
4560    for (i=0; i< drv_ctx.ip_buf.actualcount; i++) {
4561        if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
4562            DEBUG_PRINT_LOW("Free Input Buffer Index %d",i);
4563            break;
4564        }
4565    }
4566
4567    if (i < drv_ctx.ip_buf.actualcount) {
4568        DEBUG_PRINT_LOW("Allocate input Buffer");
4569
4570#ifdef USE_ION
4571        drv_ctx.ip_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4572                drv_ctx.ip_buf.buffer_size,drv_ctx.op_buf.alignment,
4573                &drv_ctx.ip_buf_ion_info[i].ion_alloc_data,
4574                &drv_ctx.ip_buf_ion_info[i].fd_ion_data,ION_FLAG_CACHED);
4575
4576        if (drv_ctx.ip_buf_ion_info[i].ion_device_fd < 0) {
4577            return OMX_ErrorInsufficientResources;
4578        }
4579
4580        pmem_fd = drv_ctx.ip_buf_ion_info[i].fd_ion_data.fd;
4581#else
4582        pmem_fd = open (MEM_DEVICE,O_RDWR);
4583
4584        if (pmem_fd < 0) {
4585            DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4586            return OMX_ErrorInsufficientResources;
4587        }
4588
4589        if (pmem_fd == 0) {
4590            pmem_fd = open (MEM_DEVICE,O_RDWR);
4591
4592            if (pmem_fd < 0) {
4593                DEBUG_PRINT_ERROR("\n open failed for pmem/adsp for input buffer");
4594                return OMX_ErrorInsufficientResources;
4595            }
4596        }
4597
4598        if (!align_pmem_buffers(pmem_fd, drv_ctx.ip_buf.buffer_size,
4599                    drv_ctx.ip_buf.alignment)) {
4600            DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4601            close(pmem_fd);
4602            return OMX_ErrorInsufficientResources;
4603        }
4604
4605#endif
4606
4607        if (!secure_mode) {
4608            buf_addr = (unsigned char *)mmap(NULL,
4609                    drv_ctx.ip_buf.buffer_size,
4610                    PROT_READ|PROT_WRITE, MAP_SHARED, pmem_fd, 0);
4611
4612            if (buf_addr == MAP_FAILED) {
4613                close(pmem_fd);
4614#ifdef USE_ION
4615                free_ion_memory(&drv_ctx.ip_buf_ion_info[i]);
4616#endif
4617                DEBUG_PRINT_ERROR("\n Map Failed to allocate input buffer");
4618                return OMX_ErrorInsufficientResources;
4619            }
4620        }
4621
4622        *bufferHdr = (m_inp_mem_ptr + i);
4623
4624        if (secure_mode)
4625            drv_ctx.ptr_inputbuffer [i].bufferaddr = *bufferHdr;
4626        else
4627            drv_ctx.ptr_inputbuffer [i].bufferaddr = buf_addr;
4628
4629        drv_ctx.ptr_inputbuffer [i].pmem_fd = pmem_fd;
4630        drv_ctx.ptr_inputbuffer [i].buffer_len = drv_ctx.ip_buf.buffer_size;
4631        drv_ctx.ptr_inputbuffer [i].mmaped_size = drv_ctx.ip_buf.buffer_size;
4632        drv_ctx.ptr_inputbuffer [i].offset = 0;
4633
4634        setbuffers.buffer_type = VDEC_BUFFER_TYPE_INPUT;
4635        memcpy (&setbuffers.buffer,&drv_ctx.ptr_inputbuffer [i],
4636                sizeof (vdec_bufferpayload));
4637        ioctl_msg.in  = &setbuffers;
4638        ioctl_msg.out = NULL;
4639
4640        if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4641                    &ioctl_msg) < 0) {
4642            DEBUG_PRINT_ERROR("\n Set Buffers Failed");
4643            return OMX_ErrorInsufficientResources;
4644        }
4645
4646        input = *bufferHdr;
4647        BITMASK_SET(&m_inp_bm_count,i);
4648        DEBUG_PRINT_LOW("Buffer address %p of pmem",*bufferHdr);
4649
4650        if (secure_mode)
4651            input->pBuffer = (OMX_U8 *)drv_ctx.ptr_inputbuffer [i].pmem_fd;
4652        else
4653            input->pBuffer           = (OMX_U8 *)buf_addr;
4654
4655        input->nSize             = sizeof(OMX_BUFFERHEADERTYPE);
4656        input->nVersion.nVersion = OMX_SPEC_VERSION;
4657        input->nAllocLen         = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH;
4658        input->pAppPrivate       = appData;
4659        input->nInputPortIndex   = OMX_CORE_INPUT_PORT_INDEX;
4660        input->pInputPortPrivate = (void *)&drv_ctx.ptr_inputbuffer [i];
4661
4662        if (drv_ctx.disable_dmx) {
4663            eRet = allocate_desc_buffer(i);
4664        }
4665    } else {
4666        DEBUG_PRINT_ERROR("\nERROR:Input Buffer Index not found");
4667        eRet = OMX_ErrorInsufficientResources;
4668    }
4669
4670    return eRet;
4671}
4672
4673
4674/* ======================================================================
4675   FUNCTION
4676   omx_vdec::AllocateOutputBuffer
4677
4678   DESCRIPTION
4679   Helper fn for AllocateBuffer in the output pin
4680
4681   PARAMETERS
4682   <TBD>.
4683
4684   RETURN VALUE
4685   OMX Error None if everything went well.
4686
4687   ========================================================================== */
4688OMX_ERRORTYPE  omx_vdec::allocate_output_buffer(
4689        OMX_IN OMX_HANDLETYPE            hComp,
4690        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
4691        OMX_IN OMX_U32                   port,
4692        OMX_IN OMX_PTR                   appData,
4693        OMX_IN OMX_U32                   bytes)
4694{
4695    OMX_ERRORTYPE eRet = OMX_ErrorNone;
4696    OMX_BUFFERHEADERTYPE       *bufHdr= NULL; // buffer header
4697    unsigned                         i= 0; // Temporary counter
4698    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
4699    struct vdec_setbuffer_cmd setbuffers;
4700#ifdef USE_ION
4701    int ion_device_fd =-1;
4702    struct ion_allocation_data ion_alloc_data;
4703    struct ion_fd_data fd_ion_data;
4704#endif
4705
4706    int nBufHdrSize        = 0;
4707    int nPlatformEntrySize = 0;
4708    int nPlatformListSize  = 0;
4709    int nPMEMInfoSize = 0;
4710    int pmem_fd = -1;
4711    unsigned char *pmem_baseaddress = NULL;
4712
4713    OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
4714    OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
4715    OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
4716
4717    if (!m_out_mem_ptr) {
4718        DEBUG_PRINT_HIGH("Allocate o/p buffer Header: Cnt(%d) Sz(%d)",
4719                drv_ctx.op_buf.actualcount,
4720                drv_ctx.op_buf.buffer_size);
4721
4722        DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)",
4723                drv_ctx.op_buf.actualcount);
4724
4725        nBufHdrSize        = drv_ctx.op_buf.actualcount *
4726            sizeof(OMX_BUFFERHEADERTYPE);
4727
4728        nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
4729            sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
4730        nPlatformListSize  = drv_ctx.op_buf.actualcount *
4731            sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
4732        nPlatformEntrySize = drv_ctx.op_buf.actualcount *
4733            sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
4734
4735        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
4736                sizeof(OMX_BUFFERHEADERTYPE),
4737                nPMEMInfoSize,
4738                nPlatformListSize);
4739        DEBUG_PRINT_LOW("PE %d OutputBuffer Count %d",nPlatformEntrySize,
4740                drv_ctx.op_buf.actualcount);
4741
4742        m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
4743        // Alloc mem for platform specific info
4744        char *pPtr=NULL;
4745        pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
4746                nPMEMInfoSize,1);
4747        drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *)\
4748                                   calloc (sizeof(struct vdec_bufferpayload),
4749                                           drv_ctx.op_buf.actualcount);
4750        drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
4751                                 calloc (sizeof (struct vdec_output_frameinfo),
4752                                         drv_ctx.op_buf.actualcount);
4753#ifdef USE_ION
4754        drv_ctx.op_buf_ion_info = (struct vdec_ion *)\
4755                                  calloc (sizeof(struct vdec_ion),
4756                                          drv_ctx.op_buf.actualcount);
4757#endif
4758#ifdef _ANDROID_
4759        m_heap_ptr = (struct vidc_heap *)\
4760                     calloc (sizeof(struct vidc_heap),
4761                             drv_ctx.op_buf.actualcount);
4762#endif
4763
4764        if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
4765                && drv_ctx.ptr_respbuffer
4766#ifdef _ANDROID_
4767                && m_heap_ptr
4768#endif
4769           ) {
4770            drv_ctx.ptr_outputbuffer[0].mmaped_size =
4771                (drv_ctx.op_buf.buffer_size *
4772                 drv_ctx.op_buf.actualcount);
4773            bufHdr          =  m_out_mem_ptr;
4774            m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
4775            m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
4776                (((char *) m_platform_list)  + nPlatformListSize);
4777            m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
4778                (((char *) m_platform_entry) + nPlatformEntrySize);
4779            pPlatformList   = m_platform_list;
4780            pPlatformEntry  = m_platform_entry;
4781            pPMEMInfo       = m_pmem_info;
4782
4783            DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
4784
4785            // Settting the entire storage nicely
4786            DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr, m_out_mem_ptr,pPlatformEntry);
4787            DEBUG_PRINT_LOW("Pmem Info = %p",pPMEMInfo);
4788
4789            for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
4790                bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
4791                bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
4792                // Set the values when we determine the right HxW param
4793                bufHdr->nAllocLen          = 0;
4794                bufHdr->nFilledLen         = 0;
4795                bufHdr->pAppPrivate        = NULL;
4796                bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
4797                // Platform specific PMEM Information
4798                // Initialize the Platform Entry
4799                //DEBUG_PRINT_LOW("Initializing the Platform Entry for %d",i);
4800                pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
4801                pPlatformEntry->entry      = pPMEMInfo;
4802                // Initialize the Platform List
4803                pPlatformList->nEntries    = 1;
4804                pPlatformList->entryList   = pPlatformEntry;
4805                // Keep pBuffer NULL till vdec is opened
4806                bufHdr->pBuffer            = NULL;
4807
4808                pPMEMInfo->offset          =  0;
4809                pPMEMInfo->pmem_fd = 0;
4810                bufHdr->pPlatformPrivate = pPlatformList;
4811                drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
4812#ifdef USE_ION
4813                drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
4814#endif
4815                /*Create a mapping between buffers*/
4816                bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
4817                drv_ctx.ptr_respbuffer[i].client_data = (void *)\
4818                                                        &drv_ctx.ptr_outputbuffer[i];
4819#ifdef _ANDROID_
4820                m_heap_ptr[i].video_heap_ptr = NULL;
4821#endif
4822                // Move the buffer and buffer header pointers
4823                bufHdr++;
4824                pPMEMInfo++;
4825                pPlatformEntry++;
4826                pPlatformList++;
4827            }
4828
4829#ifdef MAX_RES_1080P
4830
4831            if (eRet == OMX_ErrorNone && secure_mode) {
4832                eRet = vdec_alloc_meta_buffers();
4833
4834                if (eRet) {
4835                    DEBUG_PRINT_ERROR("ERROR in allocating meta buffers\n");
4836                    return OMX_ErrorInsufficientResources;
4837                }
4838            }
4839
4840            if (eRet == OMX_ErrorNone && drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
4841                //Allocate the h264_mv_buffer
4842                eRet = vdec_alloc_h264_mv();
4843
4844                if (eRet) {
4845                    DEBUG_PRINT_ERROR("ERROR in allocating MV buffers\n");
4846                    return OMX_ErrorInsufficientResources;
4847                }
4848            }
4849
4850#endif
4851        } else {
4852            DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
4853                    m_out_mem_ptr, pPtr);
4854
4855            if (m_out_mem_ptr) {
4856                free(m_out_mem_ptr);
4857                m_out_mem_ptr = NULL;
4858            }
4859
4860            if (pPtr) {
4861                free(pPtr);
4862                pPtr = NULL;
4863            }
4864
4865            if (drv_ctx.ptr_outputbuffer) {
4866                free(drv_ctx.ptr_outputbuffer);
4867                drv_ctx.ptr_outputbuffer = NULL;
4868            }
4869
4870            if (drv_ctx.ptr_respbuffer) {
4871                free(drv_ctx.ptr_respbuffer);
4872                drv_ctx.ptr_respbuffer = NULL;
4873            }
4874
4875#ifdef USE_ION
4876
4877            if (drv_ctx.op_buf_ion_info) {
4878                DEBUG_PRINT_LOW("Free o/p ion context");
4879                free(drv_ctx.op_buf_ion_info);
4880                drv_ctx.op_buf_ion_info = NULL;
4881            }
4882
4883#endif
4884            eRet =  OMX_ErrorInsufficientResources;
4885        }
4886    }
4887
4888    for (i=0; i< drv_ctx.op_buf.actualcount; i++) {
4889        if (BITMASK_ABSENT(&m_out_bm_count,i)) {
4890            DEBUG_PRINT_LOW("Found a Free Output Buffer Index %d",i);
4891            break;
4892        }
4893    }
4894
4895    if (i < drv_ctx.op_buf.actualcount) {
4896        DEBUG_PRINT_LOW("Allocate Output Buffer");
4897
4898#ifdef USE_ION
4899        drv_ctx.op_buf_ion_info[i].ion_device_fd = alloc_map_ion_memory(
4900                drv_ctx.op_buf.buffer_size,drv_ctx.op_buf.alignment,
4901                &drv_ctx.op_buf_ion_info[i].ion_alloc_data,
4902                &drv_ctx.op_buf_ion_info[i].fd_ion_data, ION_FLAG_CACHED);
4903
4904        if (drv_ctx.op_buf_ion_info[i].ion_device_fd < 0) {
4905            return OMX_ErrorInsufficientResources;
4906        }
4907
4908        pmem_fd = drv_ctx.op_buf_ion_info[i].fd_ion_data.fd;
4909#else
4910        pmem_fd = open (MEM_DEVICE,O_RDWR);
4911
4912        if (pmem_fd < 0) {
4913            DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4914                    drv_ctx.op_buf.buffer_size);
4915            return OMX_ErrorInsufficientResources;
4916        }
4917
4918        if (pmem_fd == 0) {
4919            pmem_fd = open (MEM_DEVICE,O_RDWR);
4920
4921            if (pmem_fd < 0) {
4922                DEBUG_PRINT_ERROR("\nERROR:pmem fd for output buffer %d",
4923                        drv_ctx.op_buf.buffer_size);
4924                return OMX_ErrorInsufficientResources;
4925            }
4926        }
4927
4928        if (!align_pmem_buffers(pmem_fd, drv_ctx.op_buf.buffer_size,
4929                    drv_ctx.op_buf.alignment)) {
4930            DEBUG_PRINT_ERROR("\n align_pmem_buffers() failed");
4931            close(pmem_fd);
4932            return OMX_ErrorInsufficientResources;
4933        }
4934
4935#endif
4936
4937        if (!secure_mode) {
4938            pmem_baseaddress = (unsigned char *)mmap(NULL,
4939                    drv_ctx.op_buf.buffer_size,
4940                    PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd,0);
4941
4942            if (pmem_baseaddress == MAP_FAILED) {
4943                DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",
4944                        drv_ctx.op_buf.buffer_size);
4945                close(pmem_fd);
4946#ifdef USE_ION
4947                free_ion_memory(&drv_ctx.op_buf_ion_info[i]);
4948#endif
4949                return OMX_ErrorInsufficientResources;
4950            }
4951        }
4952
4953        *bufferHdr = (m_out_mem_ptr + i);
4954
4955        if (secure_mode)
4956            drv_ctx.ptr_outputbuffer [i].bufferaddr = *bufferHdr;
4957        else
4958            drv_ctx.ptr_outputbuffer [i].bufferaddr = pmem_baseaddress;
4959
4960        drv_ctx.ptr_outputbuffer [i].pmem_fd = pmem_fd;
4961        drv_ctx.ptr_outputbuffer [i].buffer_len = drv_ctx.op_buf.buffer_size;
4962        drv_ctx.ptr_outputbuffer [i].mmaped_size = drv_ctx.op_buf.buffer_size;
4963        drv_ctx.ptr_outputbuffer [i].offset = 0;
4964
4965#ifdef _ANDROID_
4966#ifdef USE_ION
4967        m_heap_ptr[i].video_heap_ptr = new VideoHeap (drv_ctx.op_buf_ion_info[i].ion_device_fd,
4968                drv_ctx.op_buf.buffer_size,
4969                pmem_baseaddress,
4970                ion_alloc_data.handle,
4971                pmem_fd);
4972        m_heap_count = m_heap_count + 1;
4973#else
4974        m_heap_ptr[i].video_heap_ptr = new VideoHeap (pmem_fd,
4975                drv_ctx.op_buf.buffer_size,
4976                pmem_baseaddress);
4977#endif
4978#endif
4979
4980        m_pmem_info[i].offset = drv_ctx.ptr_outputbuffer[i].offset;
4981#ifdef _ANDROID_
4982        m_pmem_info[i].pmem_fd = (OMX_U32) m_heap_ptr[i].video_heap_ptr.get ();
4983#else
4984        m_pmem_info[i].pmem_fd = drv_ctx.ptr_outputbuffer[i].pmem_fd ;
4985#endif
4986        setbuffers.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
4987        memcpy (&setbuffers.buffer,&drv_ctx.ptr_outputbuffer [i],
4988                sizeof (vdec_bufferpayload));
4989        ioctl_msg.in  = &setbuffers;
4990        ioctl_msg.out = NULL;
4991
4992        DEBUG_PRINT_LOW("Set the Output Buffer Idx: %d Addr: %x", i, drv_ctx.ptr_outputbuffer[i]);
4993
4994        if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_BUFFER,
4995                    &ioctl_msg) < 0) {
4996            DEBUG_PRINT_ERROR("\n Set output buffer failed");
4997            return OMX_ErrorInsufficientResources;
4998        }
4999
5000        // found an empty buffer at i
5001        (*bufferHdr)->nAllocLen = drv_ctx.op_buf.buffer_size;
5002        (*bufferHdr)->pBuffer = (OMX_U8*)drv_ctx.ptr_outputbuffer[i].bufferaddr;
5003        (*bufferHdr)->pAppPrivate = appData;
5004        BITMASK_SET(&m_out_bm_count,i);
5005
5006    } else {
5007        DEBUG_PRINT_ERROR("\nERROR:Output Buffer Index not found");
5008        eRet = OMX_ErrorInsufficientResources;
5009    }
5010
5011    return eRet;
5012}
5013
5014
5015// AllocateBuffer  -- API Call
5016/* ======================================================================
5017   FUNCTION
5018   omx_vdec::AllocateBuffer
5019
5020   DESCRIPTION
5021   Returns zero if all the buffers released..
5022
5023   PARAMETERS
5024   None.
5025
5026   RETURN VALUE
5027   true/false
5028
5029   ========================================================================== */
5030OMX_ERRORTYPE  omx_vdec::allocate_buffer(OMX_IN OMX_HANDLETYPE                hComp,
5031        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5032        OMX_IN OMX_U32                        port,
5033        OMX_IN OMX_PTR                     appData,
5034        OMX_IN OMX_U32                       bytes)
5035{
5036    unsigned i = 0;
5037    OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
5038
5039    DEBUG_PRINT_LOW("Allocate buffer on port %d", (int)port);
5040
5041    if (m_state == OMX_StateInvalid) {
5042        DEBUG_PRINT_ERROR("Allocate Buf in Invalid State\n");
5043        return OMX_ErrorInvalidState;
5044    }
5045
5046    if (port == OMX_CORE_INPUT_PORT_INDEX) {
5047        if (arbitrary_bytes) {
5048            eRet = allocate_input_heap_buffer (hComp,bufferHdr,port,appData,bytes);
5049        } else {
5050            eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
5051        }
5052    } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
5053        eRet = client_buffers.allocate_buffers_color_convert(hComp,bufferHdr,port,
5054                appData,bytes);
5055    } else {
5056        DEBUG_PRINT_ERROR("Error: Invalid Port Index received %d\n",(int)port);
5057        eRet = OMX_ErrorBadPortIndex;
5058    }
5059
5060    DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
5061
5062    if (eRet == OMX_ErrorNone) {
5063        if (allocate_done()) {
5064            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING)) {
5065                // Send the callback now
5066                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
5067                post_event(OMX_CommandStateSet,OMX_StateIdle,
5068                        OMX_COMPONENT_GENERATE_EVENT);
5069            }
5070        }
5071
5072        if (port == OMX_CORE_INPUT_PORT_INDEX && m_inp_bPopulated) {
5073            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING)) {
5074                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
5075                post_event(OMX_CommandPortEnable,
5076                        OMX_CORE_INPUT_PORT_INDEX,
5077                        OMX_COMPONENT_GENERATE_EVENT);
5078            }
5079        }
5080
5081        if (port == OMX_CORE_OUTPUT_PORT_INDEX && m_out_bPopulated) {
5082            if (BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING)) {
5083                BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
5084                post_event(OMX_CommandPortEnable,
5085                        OMX_CORE_OUTPUT_PORT_INDEX,
5086                        OMX_COMPONENT_GENERATE_EVENT);
5087            }
5088        }
5089    }
5090
5091    DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d",eRet);
5092    return eRet;
5093}
5094
5095// Free Buffer - API call
5096/* ======================================================================
5097   FUNCTION
5098   omx_vdec::FreeBuffer
5099
5100   DESCRIPTION
5101
5102   PARAMETERS
5103   None.
5104
5105   RETURN VALUE
5106   true/false
5107
5108   ========================================================================== */
5109OMX_ERRORTYPE  omx_vdec::free_buffer(OMX_IN OMX_HANDLETYPE         hComp,
5110        OMX_IN OMX_U32                 port,
5111        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5112{
5113    OMX_ERRORTYPE eRet = OMX_ErrorNone;
5114    unsigned int nPortIndex;
5115
5116    DEBUG_PRINT_LOW("In for decoder free_buffer");
5117
5118    if (m_state == OMX_StateIdle &&
5119            (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5120        DEBUG_PRINT_LOW(" free buffer while Component in Loading pending");
5121    } else if ((m_inp_bEnabled == OMX_FALSE && port == OMX_CORE_INPUT_PORT_INDEX)||
5122            (m_out_bEnabled == OMX_FALSE && port == OMX_CORE_OUTPUT_PORT_INDEX)) {
5123        DEBUG_PRINT_LOW("Free Buffer while port %d disabled", port);
5124    } else if (m_state == OMX_StateExecuting || m_state == OMX_StatePause) {
5125        DEBUG_PRINT_ERROR("Invalid state to free buffer,ports need to be disabled\n");
5126        post_event(OMX_EventError,
5127                OMX_ErrorPortUnpopulated,
5128                OMX_COMPONENT_GENERATE_EVENT);
5129
5130        return OMX_ErrorIncorrectStateOperation;
5131    } else if (m_state != OMX_StateInvalid) {
5132        DEBUG_PRINT_ERROR("Invalid state to free buffer,port lost Buffers\n");
5133        post_event(OMX_EventError,
5134                OMX_ErrorPortUnpopulated,
5135                OMX_COMPONENT_GENERATE_EVENT);
5136    }
5137
5138    if (port == OMX_CORE_INPUT_PORT_INDEX) {
5139        /*Check if arbitrary bytes*/
5140        if (!arbitrary_bytes && !input_use_buffer)
5141            nPortIndex = buffer - m_inp_mem_ptr;
5142        else
5143            nPortIndex = buffer - m_inp_heap_ptr;
5144
5145        DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d", nPortIndex);
5146
5147        if (nPortIndex < drv_ctx.ip_buf.actualcount) {
5148            // Clear the bit associated with it.
5149            BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
5150            BITMASK_CLEAR(&m_heap_inp_bm_count,nPortIndex);
5151
5152            if (input_use_buffer == true) {
5153
5154                DEBUG_PRINT_LOW("Free pmem Buffer index %d",nPortIndex);
5155
5156                if (m_phdr_pmem_ptr)
5157                    free_input_buffer(m_phdr_pmem_ptr[nPortIndex]);
5158            } else {
5159                if (arbitrary_bytes) {
5160                    if (m_phdr_pmem_ptr)
5161                        free_input_buffer(nPortIndex,m_phdr_pmem_ptr[nPortIndex]);
5162                    else
5163                        free_input_buffer(nPortIndex,NULL);
5164                } else
5165                    free_input_buffer(buffer);
5166            }
5167
5168            m_inp_bPopulated = OMX_FALSE;
5169
5170            /*Free the Buffer Header*/
5171            if (release_input_done()) {
5172                DEBUG_PRINT_HIGH("ALL input buffers are freed/released");
5173                free_input_buffer_header();
5174            }
5175        } else {
5176            DEBUG_PRINT_ERROR("Error: free_buffer ,Port Index Invalid\n");
5177            eRet = OMX_ErrorBadPortIndex;
5178        }
5179
5180        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
5181                && release_input_done()) {
5182            DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
5183            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
5184            post_event(OMX_CommandPortDisable,
5185                    OMX_CORE_INPUT_PORT_INDEX,
5186                    OMX_COMPONENT_GENERATE_EVENT);
5187        }
5188    } else if (port == OMX_CORE_OUTPUT_PORT_INDEX) {
5189        // check if the buffer is valid
5190        nPortIndex = buffer - client_buffers.get_il_buf_hdr();
5191
5192        if (nPortIndex < drv_ctx.op_buf.actualcount) {
5193            DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d", nPortIndex);
5194            // Clear the bit associated with it.
5195            BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
5196            m_out_bPopulated = OMX_FALSE;
5197            client_buffers.free_output_buffer (buffer);
5198
5199            if (release_output_done()) {
5200                free_output_buffer_header();
5201            }
5202        } else {
5203            DEBUG_PRINT_ERROR("Error: free_buffer , Port Index Invalid\n");
5204            eRet = OMX_ErrorBadPortIndex;
5205        }
5206
5207        if (BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
5208                && release_output_done()) {
5209            DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it");
5210
5211            DEBUG_PRINT_LOW("MOVING TO DISABLED STATE");
5212            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
5213#ifdef _ANDROID_ICS_
5214
5215            if (m_enable_android_native_buffers) {
5216                DEBUG_PRINT_LOW("FreeBuffer - outport disabled: reset native buffers");
5217                memset(&native_buffer, 0 ,(sizeof(struct nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5218            }
5219
5220#endif
5221
5222            post_event(OMX_CommandPortDisable,
5223                    OMX_CORE_OUTPUT_PORT_INDEX,
5224                    OMX_COMPONENT_GENERATE_EVENT);
5225        }
5226    } else {
5227        eRet = OMX_ErrorBadPortIndex;
5228    }
5229
5230    if ((eRet == OMX_ErrorNone) &&
5231            (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING))) {
5232        if (release_done()) {
5233            // Send the callback now
5234            BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
5235            post_event(OMX_CommandStateSet, OMX_StateLoaded,
5236                    OMX_COMPONENT_GENERATE_EVENT);
5237        }
5238    }
5239
5240    return eRet;
5241}
5242
5243
5244/* ======================================================================
5245   FUNCTION
5246   omx_vdec::EmptyThisBuffer
5247
5248   DESCRIPTION
5249   This routine is used to push the encoded video frames to
5250   the video decoder.
5251
5252   PARAMETERS
5253   None.
5254
5255   RETURN VALUE
5256   OMX Error None if everything went successful.
5257
5258   ========================================================================== */
5259OMX_ERRORTYPE  omx_vdec::empty_this_buffer(OMX_IN OMX_HANDLETYPE         hComp,
5260        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5261{
5262    OMX_ERRORTYPE ret1 = OMX_ErrorNone;
5263    unsigned int nBufferIndex = drv_ctx.ip_buf.actualcount;
5264
5265    if (buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) {
5266        codec_config_flag = true;
5267        DEBUG_PRINT_LOW("%s: codec_config buffer", __FUNCTION__);
5268    } else {
5269        codec_config_flag = false;
5270    }
5271
5272    if (m_state == OMX_StateInvalid) {
5273        DEBUG_PRINT_ERROR("Empty this buffer in Invalid State\n");
5274        return OMX_ErrorInvalidState;
5275    }
5276
5277    if (buffer == NULL) {
5278        DEBUG_PRINT_ERROR("\nERROR:ETB Buffer is NULL");
5279        return OMX_ErrorBadParameter;
5280    }
5281
5282    if (!m_inp_bEnabled) {
5283        DEBUG_PRINT_ERROR("\nERROR:ETB incorrect state operation, input port is disabled.");
5284        return OMX_ErrorIncorrectStateOperation;
5285    }
5286
5287    if (buffer->nInputPortIndex != OMX_CORE_INPUT_PORT_INDEX) {
5288        DEBUG_PRINT_ERROR("\nERROR:ETB invalid port in header %d", buffer->nInputPortIndex);
5289        return OMX_ErrorBadPortIndex;
5290    }
5291
5292#ifdef _ANDROID_
5293
5294    if (iDivXDrmDecrypt) {
5295        OMX_ERRORTYPE drmErr = iDivXDrmDecrypt->Decrypt(buffer);
5296
5297        if (drmErr != OMX_ErrorNone) {
5298            // this error can be ignored
5299            DEBUG_PRINT_LOW("\nERROR:iDivXDrmDecrypt->Decrypt %d", drmErr);
5300        }
5301    }
5302
5303    if (perf_flag) {
5304        if (!latency) {
5305            dec_time.stop();
5306            latency = dec_time.processing_time_us();
5307            dec_time.start();
5308        }
5309    }
5310
5311#endif //_ANDROID_
5312
5313    if (arbitrary_bytes) {
5314        nBufferIndex = buffer - m_inp_heap_ptr;
5315    } else {
5316        if (input_use_buffer == true) {
5317            nBufferIndex = buffer - m_inp_heap_ptr;
5318            m_inp_mem_ptr[nBufferIndex].nFilledLen = m_inp_heap_ptr[nBufferIndex].nFilledLen;
5319            m_inp_mem_ptr[nBufferIndex].nTimeStamp = m_inp_heap_ptr[nBufferIndex].nTimeStamp;
5320            m_inp_mem_ptr[nBufferIndex].nFlags = m_inp_heap_ptr[nBufferIndex].nFlags;
5321            buffer = &m_inp_mem_ptr[nBufferIndex];
5322            DEBUG_PRINT_LOW("Non-Arbitrary mode - buffer address is: malloc %p, pmem%p in Index %d, buffer %p of size %d",
5323                    &m_inp_heap_ptr[nBufferIndex], &m_inp_mem_ptr[nBufferIndex],nBufferIndex, buffer, buffer->nFilledLen);
5324        } else {
5325            nBufferIndex = buffer - m_inp_mem_ptr;
5326        }
5327    }
5328
5329    if (nBufferIndex > drv_ctx.ip_buf.actualcount ) {
5330        DEBUG_PRINT_ERROR("\nERROR:ETB nBufferIndex is invalid");
5331        return OMX_ErrorBadParameter;
5332    }
5333
5334    DEBUG_PRINT_LOW("[ETB] BHdr(%p) pBuf(%p) nTS(%lld) nFL(%lu)",
5335            buffer, buffer->pBuffer, buffer->nTimeStamp, buffer->nFilledLen);
5336
5337    if (arbitrary_bytes) {
5338        post_event ((unsigned)hComp,(unsigned)buffer,
5339                OMX_COMPONENT_GENERATE_ETB_ARBITRARY);
5340    } else {
5341        if (!(client_extradata & OMX_TIMEINFO_EXTRADATA))
5342            set_frame_rate(buffer->nTimeStamp);
5343
5344        post_event ((unsigned)hComp,(unsigned)buffer,OMX_COMPONENT_GENERATE_ETB);
5345    }
5346
5347    return OMX_ErrorNone;
5348}
5349
5350/* ======================================================================
5351   FUNCTION
5352   omx_vdec::empty_this_buffer_proxy
5353
5354   DESCRIPTION
5355   This routine is used to push the encoded video frames to
5356   the video decoder.
5357
5358   PARAMETERS
5359   None.
5360
5361   RETURN VALUE
5362   OMX Error None if everything went successful.
5363
5364   ========================================================================== */
5365OMX_ERRORTYPE  omx_vdec::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE         hComp,
5366        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5367{
5368    int push_cnt = 0,i=0;
5369    unsigned nPortIndex = 0;
5370    OMX_ERRORTYPE ret = OMX_ErrorNone;
5371    struct vdec_input_frameinfo frameinfo;
5372    struct vdec_bufferpayload *temp_buffer;
5373    struct vdec_ioctl_msg ioctl_msg;
5374    struct vdec_seqheader seq_header;
5375    bool port_setting_changed = true;
5376#ifdef MAX_RES_1080P
5377    bool not_coded_vop = false;
5378#endif
5379
5380    /*Should we generate a Aync error event*/
5381    if (buffer == NULL || buffer->pInputPortPrivate == NULL) {
5382        DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy is invalid");
5383        return OMX_ErrorBadParameter;
5384    }
5385
5386    nPortIndex = buffer-((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
5387
5388    if (nPortIndex > drv_ctx.ip_buf.actualcount) {
5389        DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy invalid nPortIndex[%u]",
5390                nPortIndex);
5391        return OMX_ErrorBadParameter;
5392    }
5393
5394    pending_input_buffers++;
5395
5396    /* return zero length and not an EOS buffer */
5397    if (!arbitrary_bytes && (buffer->nFilledLen == 0) &&
5398            ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0)) {
5399        DEBUG_PRINT_HIGH("return zero legth buffer");
5400        post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5401                OMX_COMPONENT_GENERATE_EBD);
5402        return OMX_ErrorNone;
5403    }
5404
5405#ifdef MAX_RES_1080P
5406
5407    if (codec_type_parse == CODEC_TYPE_MPEG4 || codec_type_parse == CODEC_TYPE_DIVX) {
5408        mp4StreamType psBits;
5409        psBits.data = (unsigned char *)(buffer->pBuffer + buffer->nOffset);
5410        psBits.numBytes = buffer->nFilledLen;
5411        mp4_headerparser.parseHeader(&psBits);
5412        not_coded_vop = mp4_headerparser.is_notcodec_vop(
5413                (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5414
5415        if (not_coded_vop) {
5416            DEBUG_PRINT_HIGH("Found Not coded vop len %d frame number %d",
5417                    buffer->nFilledLen,frame_count);
5418
5419            if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
5420                DEBUG_PRINT_HIGH("Eos and Not coded Vop set len to zero");
5421                not_coded_vop = false;
5422                buffer->nFilledLen = 0;
5423            }
5424        }
5425    }
5426
5427#endif
5428
5429    if (input_flush_progress == true
5430#ifdef MAX_RES_1080P
5431            || not_coded_vop
5432#endif
5433       ) {
5434        DEBUG_PRINT_LOW("Flush in progress return buffer ");
5435        post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5436                OMX_COMPONENT_GENERATE_EBD);
5437        return OMX_ErrorNone;
5438    }
5439
5440    temp_buffer = (struct vdec_bufferpayload *)buffer->pInputPortPrivate;
5441
5442    if ((temp_buffer -  drv_ctx.ptr_inputbuffer) > drv_ctx.ip_buf.actualcount) {
5443        return OMX_ErrorBadParameter;
5444    }
5445
5446    DEBUG_PRINT_LOW("ETBProxy: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5447    /*for use buffer we need to memcpy the data*/
5448    temp_buffer->buffer_len = buffer->nFilledLen;
5449
5450    if (input_use_buffer) {
5451        if (buffer->nFilledLen <= temp_buffer->buffer_len) {
5452            if (arbitrary_bytes) {
5453                memcpy (temp_buffer->bufferaddr, (buffer->pBuffer + buffer->nOffset),buffer->nFilledLen);
5454            } else {
5455                memcpy (temp_buffer->bufferaddr, (m_inp_heap_ptr[nPortIndex].pBuffer + m_inp_heap_ptr[nPortIndex].nOffset),
5456                        buffer->nFilledLen);
5457            }
5458        } else {
5459            return OMX_ErrorBadParameter;
5460        }
5461
5462    }
5463
5464    frameinfo.bufferaddr = temp_buffer->bufferaddr;
5465    frameinfo.client_data = (void *) buffer;
5466    frameinfo.datalen = temp_buffer->buffer_len;
5467    frameinfo.flags = 0;
5468    frameinfo.offset = buffer->nOffset;
5469    frameinfo.pmem_fd = temp_buffer->pmem_fd;
5470    frameinfo.pmem_offset = temp_buffer->offset;
5471    frameinfo.timestamp = buffer->nTimeStamp;
5472
5473    if (drv_ctx.disable_dmx && m_desc_buffer_ptr && m_desc_buffer_ptr[nPortIndex].buf_addr) {
5474        DEBUG_PRINT_LOW("ETB: dmx enabled");
5475
5476        if (m_demux_entries == 0) {
5477            extract_demux_addr_offsets(buffer);
5478        }
5479
5480        DEBUG_PRINT_LOW("ETB: handle_demux_data - entries=%d",m_demux_entries);
5481        handle_demux_data(buffer);
5482        frameinfo.desc_addr = (OMX_U8 *)m_desc_buffer_ptr[nPortIndex].buf_addr;
5483        frameinfo.desc_size = m_desc_buffer_ptr[nPortIndex].desc_data_size;
5484    } else {
5485        frameinfo.desc_addr = NULL;
5486        frameinfo.desc_size = 0;
5487    }
5488
5489    if (!arbitrary_bytes) {
5490        frameinfo.flags |= buffer->nFlags;
5491    }
5492
5493
5494#ifdef _ANDROID_
5495
5496    if (m_debug_timestamp) {
5497        if (arbitrary_bytes) {
5498            DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5499            m_timestamp_list.insert_ts(buffer->nTimeStamp);
5500        } else if (!arbitrary_bytes && !(buffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG)) {
5501            DEBUG_PRINT_LOW("Inserting TIMESTAMP (%lld) into queue", buffer->nTimeStamp);
5502            m_timestamp_list.insert_ts(buffer->nTimeStamp);
5503        }
5504    }
5505
5506#endif
5507
5508#ifdef INPUT_BUFFER_LOG
5509
5510    if (inputBufferFile1) {
5511        fwrite((const char *)temp_buffer->bufferaddr,
5512                temp_buffer->buffer_len,1,inputBufferFile1);
5513    }
5514
5515#endif
5516
5517    if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
5518        frameinfo.flags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5519        buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
5520    }
5521
5522    if (temp_buffer->buffer_len == 0 || (buffer->nFlags & OMX_BUFFERFLAG_EOS)) {
5523        DEBUG_PRINT_HIGH("Rxd i/p EOS, Notify Driver that EOS has been reached");
5524        frameinfo.flags |= VDEC_BUFFERFLAG_EOS;
5525        h264_scratch.nFilledLen = 0;
5526        nal_count = 0;
5527        look_ahead_nal = false;
5528        frame_count = 0;
5529
5530        if (m_frame_parser.mutils)
5531            m_frame_parser.mutils->initialize_frame_checking_environment();
5532
5533        m_frame_parser.flush();
5534        h264_last_au_ts = LLONG_MAX;
5535        h264_last_au_flags = 0;
5536        memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
5537        m_demux_entries = 0;
5538    }
5539
5540    DEBUG_PRINT_LOW("[ETBP] pBuf(%p) nTS(%lld) Sz(%d)",
5541            frameinfo.bufferaddr, frameinfo.timestamp, frameinfo.datalen);
5542    ioctl_msg.in = &frameinfo;
5543    ioctl_msg.out = NULL;
5544
5545    if (ioctl(drv_ctx.video_driver_fd,VDEC_IOCTL_DECODE_FRAME,
5546                &ioctl_msg) < 0) {
5547        /*Generate an async error and move to invalid state*/
5548        DEBUG_PRINT_ERROR("\nERROR:empty_this_buffer_proxy VDEC_IOCTL_DECODE_FRAME failed");
5549
5550        if (!arbitrary_bytes) {
5551            DEBUG_PRINT_LOW("Return failed buffer");
5552            post_event ((unsigned int)buffer,VDEC_S_SUCCESS,
5553                    OMX_COMPONENT_GENERATE_EBD);
5554        }
5555
5556        return OMX_ErrorBadParameter;
5557    } else
5558        time_stamp_dts.insert_timestamp(buffer);
5559
5560    return ret;
5561}
5562
5563/* ======================================================================
5564   FUNCTION
5565   omx_vdec::FillThisBuffer
5566
5567   DESCRIPTION
5568   IL client uses this method to release the frame buffer
5569   after displaying them.
5570
5571   PARAMETERS
5572   None.
5573
5574   RETURN VALUE
5575   true/false
5576
5577   ========================================================================== */
5578OMX_ERRORTYPE  omx_vdec::fill_this_buffer(OMX_IN OMX_HANDLETYPE  hComp,
5579        OMX_IN OMX_BUFFERHEADERTYPE* buffer)
5580{
5581
5582    if (m_state == OMX_StateInvalid) {
5583        DEBUG_PRINT_ERROR("FTB in Invalid State\n");
5584        return OMX_ErrorInvalidState;
5585    }
5586
5587    if (!m_out_bEnabled) {
5588        DEBUG_PRINT_ERROR("\nERROR:FTB incorrect state operation, output port is disabled.");
5589        return OMX_ErrorIncorrectStateOperation;
5590    }
5591
5592    if (buffer == NULL ||
5593            ((buffer - client_buffers.get_il_buf_hdr()) >= drv_ctx.op_buf.actualcount)) {
5594        return OMX_ErrorBadParameter;
5595    }
5596
5597    if (buffer->nOutputPortIndex != OMX_CORE_OUTPUT_PORT_INDEX) {
5598        DEBUG_PRINT_ERROR("\nERROR:FTB invalid port in header %d", buffer->nOutputPortIndex);
5599        return OMX_ErrorBadPortIndex;
5600    }
5601
5602    DEBUG_PRINT_LOW("[FTB] bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
5603    post_event((unsigned) hComp, (unsigned)buffer,m_fill_output_msg);
5604    return OMX_ErrorNone;
5605}
5606/* ======================================================================
5607   FUNCTION
5608   omx_vdec::fill_this_buffer_proxy
5609
5610   DESCRIPTION
5611   IL client uses this method to release the frame buffer
5612   after displaying them.
5613
5614   PARAMETERS
5615   None.
5616
5617   RETURN VALUE
5618   true/false
5619
5620   ========================================================================== */
5621OMX_ERRORTYPE  omx_vdec::fill_this_buffer_proxy(
5622        OMX_IN OMX_HANDLETYPE        hComp,
5623        OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
5624{
5625    OMX_ERRORTYPE nRet = OMX_ErrorNone;
5626    struct vdec_ioctl_msg ioctl_msg = {NULL,NULL};
5627    OMX_BUFFERHEADERTYPE *buffer = bufferAdd;
5628    struct vdec_fillbuffer_cmd fillbuffer;
5629    struct vdec_bufferpayload     *ptr_outputbuffer = NULL;
5630    struct vdec_output_frameinfo  *ptr_respbuffer = NULL;
5631
5632
5633    if (bufferAdd == NULL || ((buffer - client_buffers.get_il_buf_hdr()) >
5634                drv_ctx.op_buf.actualcount) )
5635        return OMX_ErrorBadParameter;
5636
5637    DEBUG_PRINT_LOW("FTBProxy: bufhdr = %p, bufhdr->pBuffer = %p",
5638            bufferAdd, bufferAdd->pBuffer);
5639
5640    /*Return back the output buffer to client*/
5641    if (m_out_bEnabled != OMX_TRUE || output_flush_progress == true) {
5642        DEBUG_PRINT_LOW("Output Buffers return flush/disable condition");
5643        buffer->nFilledLen = 0;
5644        m_cb.FillBufferDone (hComp,m_app_data,buffer);
5645        return OMX_ErrorNone;
5646    }
5647
5648    pending_output_buffers++;
5649    buffer = client_buffers.get_dr_buf_hdr(bufferAdd);
5650    ptr_respbuffer = (struct vdec_output_frameinfo*)buffer->pOutputPortPrivate;
5651
5652    if (ptr_respbuffer) {
5653        ptr_outputbuffer =  (struct vdec_bufferpayload*)ptr_respbuffer->client_data;
5654    }
5655
5656    if (ptr_respbuffer == NULL || ptr_outputbuffer == NULL) {
5657        DEBUG_PRINT_ERROR("resp buffer or outputbuffer is NULL");
5658        buffer->nFilledLen = 0;
5659        m_cb.FillBufferDone (hComp,m_app_data,buffer);
5660        pending_output_buffers--;
5661        return OMX_ErrorBadParameter;
5662    }
5663
5664    memcpy (&fillbuffer.buffer,ptr_outputbuffer,\
5665            sizeof(struct vdec_bufferpayload));
5666    fillbuffer.client_data = buffer;
5667
5668#ifdef _ANDROID_ICS_
5669
5670    if (m_enable_android_native_buffers) {
5671        // Acquire a write lock on this buffer.
5672        if (GENLOCK_NO_ERROR != genlock_lock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle,
5673                    GENLOCK_WRITE_LOCK, GENLOCK_MAX_TIMEOUT)) {
5674            DEBUG_PRINT_ERROR("Failed to acquire genlock");
5675            buffer->nFilledLen = 0;
5676            m_cb.FillBufferDone (hComp,m_app_data,buffer);
5677            pending_output_buffers--;
5678            return OMX_ErrorInsufficientResources;
5679        } else {
5680            native_buffer[buffer - m_out_mem_ptr].inuse = true;
5681        }
5682    }
5683
5684#endif
5685
5686    ioctl_msg.in = &fillbuffer;
5687    ioctl_msg.out = NULL;
5688
5689    if (ioctl (drv_ctx.video_driver_fd,
5690                VDEC_IOCTL_FILL_OUTPUT_BUFFER,&ioctl_msg) < 0) {
5691        DEBUG_PRINT_ERROR("\n Decoder frame failed");
5692#ifdef _ANDROID_ICS_
5693
5694        if (m_enable_android_native_buffers) {
5695            // Unlock the buffer
5696            if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
5697                DEBUG_PRINT_ERROR("Releasing genlock failed");
5698                return OMX_ErrorInsufficientResources;
5699            } else {
5700                native_buffer[buffer - m_out_mem_ptr].inuse = false;
5701            }
5702        }
5703
5704#endif
5705        m_cb.FillBufferDone (hComp,m_app_data,buffer);
5706        pending_output_buffers--;
5707        return OMX_ErrorBadParameter;
5708    }
5709
5710    return OMX_ErrorNone;
5711}
5712
5713/* ======================================================================
5714   FUNCTION
5715   omx_vdec::SetCallbacks
5716
5717   DESCRIPTION
5718   Set the callbacks.
5719
5720   PARAMETERS
5721   None.
5722
5723   RETURN VALUE
5724   OMX Error None if everything successful.
5725
5726   ========================================================================== */
5727OMX_ERRORTYPE  omx_vdec::set_callbacks(OMX_IN OMX_HANDLETYPE        hComp,
5728        OMX_IN OMX_CALLBACKTYPE* callbacks,
5729        OMX_IN OMX_PTR             appData)
5730{
5731
5732    m_cb       = *callbacks;
5733    DEBUG_PRINT_LOW("Callbacks Set %p %p %p",m_cb.EmptyBufferDone,\
5734            m_cb.EventHandler,m_cb.FillBufferDone);
5735    m_app_data =    appData;
5736    return OMX_ErrorNotImplemented;
5737}
5738
5739/* ======================================================================
5740   FUNCTION
5741   omx_vdec::ComponentDeInit
5742
5743   DESCRIPTION
5744   Destroys the component and release memory allocated to the heap.
5745
5746   PARAMETERS
5747   <TBD>.
5748
5749   RETURN VALUE
5750   OMX Error None if everything successful.
5751
5752   ========================================================================== */
5753OMX_ERRORTYPE  omx_vdec::component_deinit(OMX_IN OMX_HANDLETYPE hComp)
5754{
5755#ifndef JB_MR1
5756    sp<IServiceManager> sm;
5757    sp<hwcService::IHWComposer> hwcBinder = NULL;
5758#endif
5759#ifdef _ANDROID_
5760
5761    if (iDivXDrmDecrypt) {
5762        delete iDivXDrmDecrypt;
5763        iDivXDrmDecrypt=NULL;
5764    }
5765
5766#endif //_ANDROID_
5767    int i = 0;
5768
5769    if (OMX_StateLoaded != m_state) {
5770        DEBUG_PRINT_ERROR("WARNING:Rxd DeInit,OMX not in LOADED state %d\n",\
5771                m_state);
5772        DEBUG_PRINT_ERROR("\nPlayback Ended - FAILED");
5773    } else {
5774        DEBUG_PRINT_HIGH("Playback Ended - PASSED");
5775    }
5776
5777#ifndef JB_MR1
5778
5779    if (secure_mode) {
5780        sm = defaultServiceManager();
5781        hwcBinder =
5782            interface_cast<hwcService::IHWComposer>(sm->getService(String16("display.hwcservice")));
5783
5784        if (hwcBinder != NULL) {
5785            hwcBinder->setCloseSecureStart();
5786        } else {
5787            DEBUG_PRINT_HIGH("Failed to get hwcbinder, "
5788                    "failed to call close secure start");
5789        }
5790    }
5791
5792#endif
5793
5794    /*Check if the output buffers have to be cleaned up*/
5795    if (m_out_mem_ptr) {
5796        DEBUG_PRINT_LOW("Freeing the Output Memory");
5797
5798        for (i=0; i < drv_ctx.op_buf.actualcount; i++ ) {
5799            free_output_buffer (&m_out_mem_ptr[i]);
5800#ifdef _ANDROID_ICS_
5801
5802            if (m_enable_android_native_buffers) {
5803                if (native_buffer[i].inuse) {
5804                    if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[i].nativehandle)) {
5805                        DEBUG_PRINT_ERROR("Unlocking genlock failed");
5806                    }
5807
5808                    native_buffer[i].inuse = false;
5809                }
5810            }
5811
5812#endif
5813        }
5814
5815#ifdef _ANDROID_ICS_
5816        memset(&native_buffer, 0, (sizeof(nativebuffer) * MAX_NUM_INPUT_OUTPUT_BUFFERS));
5817#endif
5818    }
5819
5820    /*Check if the input buffers have to be cleaned up*/
5821    if (m_inp_mem_ptr || m_inp_heap_ptr) {
5822        DEBUG_PRINT_LOW("Freeing the Input Memory");
5823
5824        for (i=0; i<drv_ctx.ip_buf.actualcount; i++ ) {
5825            if (m_inp_mem_ptr)
5826                free_input_buffer (i,&m_inp_mem_ptr[i]);
5827            else
5828                free_input_buffer (i,NULL);
5829        }
5830    }
5831
5832    free_input_buffer_header();
5833    free_output_buffer_header();
5834
5835    if (h264_scratch.pBuffer) {
5836        free(h264_scratch.pBuffer);
5837        h264_scratch.pBuffer = NULL;
5838    }
5839
5840    if (h264_parser) {
5841        delete h264_parser;
5842        h264_parser = NULL;
5843    }
5844
5845    if (m_platform_list) {
5846        free(m_platform_list);
5847        m_platform_list = NULL;
5848    }
5849
5850    if (m_vendor_config.pData) {
5851        free(m_vendor_config.pData);
5852        m_vendor_config.pData = NULL;
5853    }
5854
5855    // Reset counters in mesg queues
5856    m_ftb_q.m_size=0;
5857    m_cmd_q.m_size=0;
5858    m_etb_q.m_size=0;
5859    m_ftb_q.m_read = m_ftb_q.m_write =0;
5860    m_cmd_q.m_read = m_cmd_q.m_write =0;
5861    m_etb_q.m_read = m_etb_q.m_write =0;
5862#ifdef _ANDROID_
5863
5864    if (m_debug_timestamp) {
5865        m_timestamp_list.reset_ts_list();
5866    }
5867
5868#endif
5869
5870    DEBUG_PRINT_LOW("Calling VDEC_IOCTL_STOP_NEXT_MSG");
5871    (void)ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_STOP_NEXT_MSG,
5872            NULL);
5873#ifdef _ANDROID_
5874
5875    /* get strong count gets the refernce count of the pmem, the count will
5876     * be incremented by our kernal driver and surface flinger, by the time
5877     * we close the pmem, this cound needs to be zero, but there is no way
5878     * for us to know when surface flinger reduces its cound, so we wait
5879     * here in a infinite loop till the count is zero
5880     */
5881    if (m_heap_ptr) {
5882        for (int indx = 0; indx < drv_ctx.op_buf.actualcount; indx++)
5883            m_heap_ptr[indx].video_heap_ptr = NULL;
5884
5885        free(m_heap_ptr);
5886        m_heap_ptr = NULL;
5887        m_heap_count = 0;
5888    }
5889
5890#endif // _ANDROID_
5891#ifdef INPUT_BUFFER_LOG
5892    fclose (inputBufferFile1);
5893#endif
5894#ifdef OUTPUT_BUFFER_LOG
5895    fclose (outputBufferFile1);
5896#endif
5897#ifdef OUTPUT_EXTRADATA_LOG
5898    fclose (outputExtradataFile);
5899#endif
5900    power_module_deregister();
5901    DEBUG_PRINT_HIGH("omx_vdec::component_deinit() complete");
5902#ifndef JB_MR1
5903
5904    if (secure_mode) {
5905        if (hwcBinder != NULL) {
5906            hwcBinder->setCloseSecureEnd();
5907        } else {
5908            DEBUG_PRINT_HIGH("Failed to get hwcbinder, "
5909                    "failed to call close secure start");
5910        }
5911    }
5912
5913#endif
5914    return OMX_ErrorNone;
5915}
5916
5917/* ======================================================================
5918   FUNCTION
5919   omx_vdec::UseEGLImage
5920
5921   DESCRIPTION
5922   OMX Use EGL Image method implementation <TBD>.
5923
5924   PARAMETERS
5925   <TBD>.
5926
5927   RETURN VALUE
5928   Not Implemented error.
5929
5930   ========================================================================== */
5931OMX_ERRORTYPE  omx_vdec::use_EGL_image(OMX_IN OMX_HANDLETYPE                hComp,
5932        OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
5933        OMX_IN OMX_U32                        port,
5934        OMX_IN OMX_PTR                     appData,
5935        OMX_IN void*                      eglImage)
5936{
5937    OMX_QCOM_PLATFORM_PRIVATE_LIST pmem_list;
5938    OMX_QCOM_PLATFORM_PRIVATE_ENTRY pmem_entry;
5939    OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO pmem_info;
5940
5941#ifdef USE_EGL_IMAGE_GPU
5942    PFNEGLQUERYIMAGEQUALCOMMPROC egl_queryfunc;
5943    EGLint fd = -1, offset = 0,pmemPtr = 0;
5944#else
5945    int fd = -1, offset = 0;
5946#endif
5947    DEBUG_PRINT_HIGH("use EGL image support for decoder");
5948
5949    if (!bufferHdr || !eglImage|| port != OMX_CORE_OUTPUT_PORT_INDEX) {
5950        DEBUG_PRINT_ERROR("\n ");
5951    }
5952
5953#ifdef USE_EGL_IMAGE_GPU
5954
5955    if (m_display_id == NULL) {
5956        DEBUG_PRINT_ERROR("Display ID is not set by IL client \n");
5957        return OMX_ErrorInsufficientResources;
5958    }
5959
5960    egl_queryfunc = (PFNEGLQUERYIMAGEQUALCOMMPROC)
5961        eglGetProcAddress("eglQueryImageKHR");
5962    egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_HANDLE_QCOM,&fd);
5963    egl_queryfunc(m_display_id, eglImage, EGL_BUFFER_OFFSET_QCOM,&offset);
5964    egl_queryfunc(m_display_id, eglImage, EGL_BITMAP_POINTER_KHR,&pmemPtr);
5965#else //with OMX test app
5966    struct temp_egl {
5967        int pmem_fd;
5968        int offset;
5969    };
5970    struct temp_egl *temp_egl_id = NULL;
5971    void * pmemPtr = (void *) eglImage;
5972    temp_egl_id = (struct temp_egl *)eglImage;
5973
5974    if (temp_egl_id != NULL) {
5975        fd = temp_egl_id->pmem_fd;
5976        offset = temp_egl_id->offset;
5977    }
5978
5979#endif
5980
5981    if (fd < 0) {
5982        DEBUG_PRINT_ERROR("Improper pmem fd by EGL client %d  \n",fd);
5983        return OMX_ErrorInsufficientResources;
5984    }
5985
5986    pmem_info.pmem_fd = (OMX_U32) fd;
5987    pmem_info.offset = (OMX_U32) offset;
5988    pmem_entry.entry = (void *) &pmem_info;
5989    pmem_entry.type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
5990    pmem_list.entryList = &pmem_entry;
5991    pmem_list.nEntries = 1;
5992    ouput_egl_buffers = true;
5993
5994    if (OMX_ErrorNone != use_buffer(hComp,bufferHdr, port,
5995                (void *)&pmem_list, drv_ctx.op_buf.buffer_size,
5996                (OMX_U8 *)pmemPtr)) {
5997        DEBUG_PRINT_ERROR("use buffer call failed for egl image\n");
5998        return OMX_ErrorInsufficientResources;
5999    }
6000
6001    return OMX_ErrorNone;
6002}
6003
6004/* ======================================================================
6005   FUNCTION
6006   omx_vdec::ComponentRoleEnum
6007
6008   DESCRIPTION
6009   OMX Component Role Enum method implementation.
6010
6011   PARAMETERS
6012   <TBD>.
6013
6014   RETURN VALUE
6015   OMX Error None if everything is successful.
6016   ========================================================================== */
6017OMX_ERRORTYPE  omx_vdec::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
6018        OMX_OUT OMX_U8*        role,
6019        OMX_IN OMX_U32        index)
6020{
6021    OMX_ERRORTYPE eRet = OMX_ErrorNone;
6022
6023    if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE)) {
6024        if ((0 == index) && role) {
6025            strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
6026            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6027        } else {
6028            eRet = OMX_ErrorNoMore;
6029        }
6030    }
6031
6032    if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE)) {
6033        if ((0 == index) && role) {
6034            strlcpy((char *)role, "video_decoder.mpeg2",OMX_MAX_STRINGNAME_SIZE);
6035            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6036        } else {
6037            eRet = OMX_ErrorNoMore;
6038        }
6039    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE)) {
6040        if ((0 == index) && role) {
6041            strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
6042            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6043        } else {
6044            DEBUG_PRINT_LOW("No more roles");
6045            eRet = OMX_ErrorNoMore;
6046        }
6047    }
6048
6049#ifdef MAX_RES_1080P
6050    else if ((!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE)) ||
6051            (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx311",OMX_MAX_STRINGNAME_SIZE))
6052            )
6053#else
6054    else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.divx",OMX_MAX_STRINGNAME_SIZE))
6055#endif
6056    {
6057
6058        if ((0 == index) && role) {
6059            strlcpy((char *)role, "video_decoder.divx",OMX_MAX_STRINGNAME_SIZE);
6060            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6061        } else {
6062            DEBUG_PRINT_LOW("No more roles");
6063            eRet = OMX_ErrorNoMore;
6064        }
6065    } else if (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE)) {
6066        if ((0 == index) && role) {
6067            strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
6068            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6069        } else {
6070            DEBUG_PRINT_LOW("No more roles");
6071            eRet = OMX_ErrorNoMore;
6072        }
6073    } else if ( (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE)) ||
6074            (!strncmp(drv_ctx.kind, "OMX.qcom.video.decoder.wmv",OMX_MAX_STRINGNAME_SIZE))
6075            ) {
6076        if ((0 == index) && role) {
6077            strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
6078            DEBUG_PRINT_LOW("component_role_enum: role %s",role);
6079        } else {
6080            DEBUG_PRINT_LOW("No more roles");
6081            eRet = OMX_ErrorNoMore;
6082        }
6083    } else {
6084        DEBUG_PRINT_ERROR("\nERROR:Querying Role on Unknown Component");
6085        eRet = OMX_ErrorInvalidComponentName;
6086    }
6087
6088    return eRet;
6089}
6090
6091
6092
6093
6094/* ======================================================================
6095   FUNCTION
6096   omx_vdec::AllocateDone
6097
6098   DESCRIPTION
6099   Checks if entire buffer pool is allocated by IL Client or not.
6100   Need this to move to IDLE state.
6101
6102   PARAMETERS
6103   None.
6104
6105   RETURN VALUE
6106   true/false.
6107
6108   ========================================================================== */
6109bool omx_vdec::allocate_done(void)
6110{
6111    bool bRet = false;
6112    bool bRet_In = false;
6113    bool bRet_Out = false;
6114
6115    bRet_In = allocate_input_done();
6116    bRet_Out = allocate_output_done();
6117
6118    if (bRet_In && bRet_Out) {
6119        bRet = true;
6120    }
6121
6122    return bRet;
6123}
6124/* ======================================================================
6125   FUNCTION
6126   omx_vdec::AllocateInputDone
6127
6128   DESCRIPTION
6129   Checks if I/P buffer pool is allocated by IL Client or not.
6130
6131   PARAMETERS
6132   None.
6133
6134   RETURN VALUE
6135   true/false.
6136
6137   ========================================================================== */
6138bool omx_vdec::allocate_input_done(void)
6139{
6140    bool bRet = false;
6141    unsigned i=0;
6142
6143    if (m_inp_mem_ptr == NULL) {
6144        return bRet;
6145    }
6146
6147    if (m_inp_mem_ptr ) {
6148        for (; i<drv_ctx.ip_buf.actualcount; i++) {
6149            if (BITMASK_ABSENT(&m_inp_bm_count,i)) {
6150                break;
6151            }
6152        }
6153    }
6154
6155    if (i == drv_ctx.ip_buf.actualcount) {
6156        bRet = true;
6157        DEBUG_PRINT_HIGH("Allocate done for all i/p buffers");
6158    }
6159
6160    if (i==drv_ctx.ip_buf.actualcount && m_inp_bEnabled) {
6161        m_inp_bPopulated = OMX_TRUE;
6162    }
6163
6164    return bRet;
6165}
6166/* ======================================================================
6167   FUNCTION
6168   omx_vdec::AllocateOutputDone
6169
6170   DESCRIPTION
6171   Checks if entire O/P buffer pool is allocated by IL Client or not.
6172
6173   PARAMETERS
6174   None.
6175
6176   RETURN VALUE
6177   true/false.
6178
6179   ========================================================================== */
6180bool omx_vdec::allocate_output_done(void)
6181{
6182    bool bRet = false;
6183    unsigned j=0;
6184
6185    if (m_out_mem_ptr == NULL) {
6186        return bRet;
6187    }
6188
6189    if (m_out_mem_ptr) {
6190        for (; j < drv_ctx.op_buf.actualcount; j++) {
6191            if (BITMASK_ABSENT(&m_out_bm_count,j)) {
6192                break;
6193            }
6194        }
6195    }
6196
6197    if (j == drv_ctx.op_buf.actualcount) {
6198        bRet = true;
6199        DEBUG_PRINT_HIGH("Allocate done for all o/p buffers");
6200
6201        if (m_out_bEnabled)
6202            m_out_bPopulated = OMX_TRUE;
6203    }
6204
6205    return bRet;
6206}
6207
6208/* ======================================================================
6209   FUNCTION
6210   omx_vdec::ReleaseDone
6211
6212   DESCRIPTION
6213   Checks if IL client has released all the buffers.
6214
6215   PARAMETERS
6216   None.
6217
6218   RETURN VALUE
6219   true/false
6220
6221   ========================================================================== */
6222bool omx_vdec::release_done(void)
6223{
6224    bool bRet = false;
6225
6226    if (release_input_done()) {
6227        if (release_output_done()) {
6228            bRet = true;
6229        }
6230    }
6231
6232    return bRet;
6233}
6234
6235
6236/* ======================================================================
6237   FUNCTION
6238   omx_vdec::ReleaseOutputDone
6239
6240   DESCRIPTION
6241   Checks if IL client has released all the buffers.
6242
6243   PARAMETERS
6244   None.
6245
6246   RETURN VALUE
6247   true/false
6248
6249   ========================================================================== */
6250bool omx_vdec::release_output_done(void)
6251{
6252    bool bRet = false;
6253    unsigned i=0,j=0;
6254
6255    DEBUG_PRINT_LOW("Value of m_out_mem_ptr %p",m_inp_mem_ptr);
6256
6257    if (m_out_mem_ptr) {
6258        for (; j < drv_ctx.op_buf.actualcount ; j++) {
6259            if (BITMASK_PRESENT(&m_out_bm_count,j)) {
6260                break;
6261            }
6262        }
6263
6264        if (j == drv_ctx.op_buf.actualcount) {
6265            m_out_bm_count = 0;
6266            bRet = true;
6267        }
6268    } else {
6269        m_out_bm_count = 0;
6270        bRet = true;
6271    }
6272
6273    return bRet;
6274}
6275/* ======================================================================
6276   FUNCTION
6277   omx_vdec::ReleaseInputDone
6278
6279   DESCRIPTION
6280   Checks if IL client has released all the buffers.
6281
6282   PARAMETERS
6283   None.
6284
6285   RETURN VALUE
6286   true/false
6287
6288   ========================================================================== */
6289bool omx_vdec::release_input_done(void)
6290{
6291    bool bRet = false;
6292    unsigned i=0,j=0;
6293
6294    DEBUG_PRINT_LOW("Value of m_inp_mem_ptr %p",m_inp_mem_ptr);
6295
6296    if (m_inp_mem_ptr) {
6297        for (; j<drv_ctx.ip_buf.actualcount; j++) {
6298            if ( BITMASK_PRESENT(&m_inp_bm_count,j)) {
6299                break;
6300            }
6301        }
6302
6303        if (j==drv_ctx.ip_buf.actualcount) {
6304            bRet = true;
6305        }
6306    } else {
6307        bRet = true;
6308    }
6309
6310    return bRet;
6311}
6312
6313OMX_ERRORTYPE omx_vdec::fill_buffer_done(OMX_HANDLETYPE hComp,
6314        OMX_BUFFERHEADERTYPE * buffer)
6315{
6316    OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo = NULL;
6317
6318    if (!buffer || (buffer - m_out_mem_ptr) >= drv_ctx.op_buf.actualcount) {
6319        DEBUG_PRINT_ERROR("\n [FBD] ERROR in ptr(%p)", buffer);
6320        return OMX_ErrorBadParameter;
6321    } else if (output_flush_progress) {
6322        DEBUG_PRINT_LOW("FBD: Buffer (%p) flushed", buffer);
6323        buffer->nFilledLen = 0;
6324        buffer->nTimeStamp = 0;
6325        buffer->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
6326        buffer->nFlags &= ~QOMX_VIDEO_BUFFERFLAG_EOSEQ;
6327        buffer->nFlags &= ~OMX_BUFFERFLAG_DATACORRUPT;
6328    }
6329
6330#ifdef _ANDROID_
6331    char value[PROPERTY_VALUE_MAX];
6332    property_get("vidc.dec.debug.panframedata", value, NULL);
6333
6334    if (atoi(value)) {
6335        if (buffer->nFlags & QOMX_VIDEO_BUFFERFLAG_EOSEQ) {
6336            DEBUG_PRINT_HIGH("\n");
6337            DEBUG_PRINT_HIGH("***************************************************\n");
6338            DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received\n");
6339            DEBUG_PRINT_HIGH("***************************************************\n");
6340        }
6341
6342        if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
6343            DEBUG_PRINT_HIGH("\n");
6344            DEBUG_PRINT_HIGH("***************************************************\n");
6345            DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received\n");
6346            DEBUG_PRINT_HIGH("***************************************************\n");
6347        }
6348    }
6349
6350#endif
6351
6352    DEBUG_PRINT_LOW("fill_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6353            buffer, buffer->pBuffer);
6354    pending_output_buffers --;
6355
6356    if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6357        DEBUG_PRINT_HIGH("Output EOS has been reached");
6358
6359        if (!output_flush_progress)
6360            post_event(NULL,NULL,OMX_COMPONENT_GENERATE_EOS_DONE);
6361
6362        if (psource_frame) {
6363            m_cb.EmptyBufferDone(&m_cmp, m_app_data, psource_frame);
6364            psource_frame = NULL;
6365        }
6366
6367        if (pdest_frame) {
6368            pdest_frame->nFilledLen = 0;
6369            m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6370            pdest_frame = NULL;
6371        }
6372    }
6373
6374    DEBUG_PRINT_LOW("In fill Buffer done call address %p ",buffer);
6375#ifdef OUTPUT_BUFFER_LOG
6376
6377    if (outputBufferFile1) {
6378        OMX_U32 index = buffer - m_out_mem_ptr;
6379        OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr;
6380
6381        fwrite (pBuffer,1,buffer->nFilledLen,
6382                outputBufferFile1);
6383    }
6384
6385#endif
6386
6387    /* For use buffer we need to copy the data */
6388    if (!output_flush_progress) {
6389        time_stamp_dts.get_next_timestamp(buffer,
6390                (drv_ctx.interlace != VDEC_InterlaceFrameProgressive)
6391                ?true:false);
6392    }
6393
6394    if (m_cb.FillBufferDone) {
6395        if (buffer->nFilledLen > 0) {
6396            if (client_extradata) {
6397                if (secure_mode)
6398                    handle_extradata_secure(buffer);
6399                else
6400                    handle_extradata(buffer);
6401            }
6402
6403            if (client_extradata & OMX_TIMEINFO_EXTRADATA)
6404                // Keep min timestamp interval to handle corrupted bit stream scenario
6405                set_frame_rate(buffer->nTimeStamp);
6406            else if (arbitrary_bytes)
6407                adjust_timestamp(buffer->nTimeStamp);
6408
6409#ifdef _ANDROID_
6410
6411            if (perf_flag) {
6412                if (!proc_frms) {
6413                    dec_time.stop();
6414                    latency = dec_time.processing_time_us() - latency;
6415                    DEBUG_PRINT_HIGH(">>> FBD Metrics: Latency(%.2f)mS", latency / 1e3);
6416                    dec_time.start();
6417                    fps_metrics.start();
6418                }
6419
6420                proc_frms++;
6421
6422                if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6423                    OMX_U64 proc_time = 0;
6424                    fps_metrics.stop();
6425                    proc_time = fps_metrics.processing_time_us();
6426                    DEBUG_PRINT_HIGH(">>> FBD Metrics: proc_frms(%lu) proc_time(%.2f)S fps(%.2f)",
6427                            proc_frms, (float)proc_time / 1e6,
6428                            (float)(1e6 * proc_frms) / proc_time);
6429                    proc_frms = 0;
6430                }
6431            }
6432
6433#endif //_ANDROID_
6434
6435#ifdef OUTPUT_EXTRADATA_LOG
6436
6437            if (outputExtradataFile) {
6438
6439                OMX_U32 index = buffer - m_out_mem_ptr;
6440                OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr;
6441
6442                OMX_OTHER_EXTRADATATYPE *p_extra = NULL;
6443                p_extra = (OMX_OTHER_EXTRADATATYPE *)
6444                    ((unsigned)(pBuffer + buffer->nOffset +
6445                        buffer->nFilledLen + 3)&(~3));
6446
6447                while (p_extra &&
6448                        (OMX_U8*)p_extra < (pBuffer + buffer->nAllocLen) ) {
6449                    DEBUG_PRINT_LOW("WRITING extradata, size=%d,type=%d",p_extra->nSize, p_extra->eType);
6450                    fwrite (p_extra,1,p_extra->nSize,outputExtradataFile);
6451
6452                    if (p_extra->eType == OMX_ExtraDataNone) {
6453                        break;
6454                    }
6455
6456                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
6457                }
6458            }
6459
6460#endif
6461        }
6462
6463        if (buffer->nFlags & OMX_BUFFERFLAG_EOS) {
6464            prev_ts = LLONG_MAX;
6465            rst_prev_ts = true;
6466        }
6467
6468        pPMEMInfo = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
6469            ((OMX_QCOM_PLATFORM_PRIVATE_LIST *)
6470             buffer->pPlatformPrivate)->entryList->entry;
6471        DEBUG_PRINT_LOW("Before FBD callback Accessed Pmeminfo %d",pPMEMInfo->pmem_fd);
6472#ifdef _ANDROID_ICS_
6473
6474        if (m_enable_android_native_buffers) {
6475            if (native_buffer[buffer - m_out_mem_ptr].inuse) {
6476                if (GENLOCK_NO_ERROR != genlock_unlock_buffer(native_buffer[buffer - m_out_mem_ptr].nativehandle)) {
6477                    DEBUG_PRINT_ERROR("Unlocking genlock failed");
6478                    return OMX_ErrorInsufficientResources;
6479                } else {
6480                    native_buffer[buffer - m_out_mem_ptr].inuse = false;
6481                }
6482            }
6483        }
6484
6485#endif
6486        OMX_BUFFERHEADERTYPE *il_buffer;
6487        il_buffer = client_buffers.get_il_buf_hdr(buffer);
6488
6489        if (il_buffer)
6490            m_cb.FillBufferDone (hComp,m_app_data,il_buffer);
6491        else {
6492            DEBUG_PRINT_ERROR("Invalid buffer address from get_il_buf_hdr");
6493            return OMX_ErrorBadParameter;
6494        }
6495
6496        DEBUG_PRINT_LOW("After Fill Buffer Done callback %d",pPMEMInfo->pmem_fd);
6497    } else {
6498        return OMX_ErrorBadParameter;
6499    }
6500
6501    return OMX_ErrorNone;
6502}
6503
6504OMX_ERRORTYPE omx_vdec::empty_buffer_done(OMX_HANDLETYPE         hComp,
6505        OMX_BUFFERHEADERTYPE* buffer)
6506{
6507
6508    if (buffer == NULL || ((buffer - m_inp_mem_ptr) > drv_ctx.ip_buf.actualcount)) {
6509        DEBUG_PRINT_ERROR("\n empty_buffer_done: ERROR bufhdr = %p", buffer);
6510        return OMX_ErrorBadParameter;
6511    }
6512
6513    DEBUG_PRINT_LOW("empty_buffer_done: bufhdr = %p, bufhdr->pBuffer = %p",
6514            buffer, buffer->pBuffer);
6515    pending_input_buffers--;
6516
6517    if (arbitrary_bytes) {
6518        if (pdest_frame == NULL && input_flush_progress == false) {
6519            DEBUG_PRINT_LOW("Push input from buffer done address of Buffer %p",buffer);
6520            pdest_frame = buffer;
6521            buffer->nFilledLen = 0;
6522            buffer->nTimeStamp = LLONG_MAX;
6523            push_input_buffer (hComp);
6524        } else {
6525            DEBUG_PRINT_LOW("Push buffer into freeq address of Buffer %p",buffer);
6526            buffer->nFilledLen = 0;
6527
6528            if (!m_input_free_q.insert_entry((unsigned)buffer,NULL,NULL)) {
6529                DEBUG_PRINT_ERROR("\nERROR:i/p free Queue is FULL Error");
6530            }
6531        }
6532    } else if (m_cb.EmptyBufferDone) {
6533        buffer->nFilledLen = 0;
6534
6535        if (input_use_buffer == true) {
6536            buffer = &m_inp_heap_ptr[buffer-m_inp_mem_ptr];
6537        }
6538
6539        m_cb.EmptyBufferDone(hComp ,m_app_data, buffer);
6540    }
6541
6542    return OMX_ErrorNone;
6543}
6544
6545
6546int omx_vdec::async_message_process (void *context, void* message)
6547{
6548    omx_vdec* omx = NULL;
6549    struct vdec_msginfo *vdec_msg = NULL;
6550    OMX_BUFFERHEADERTYPE* omxhdr = NULL;
6551    struct vdec_output_frameinfo *output_respbuf = NULL;
6552
6553    if (context == NULL || message == NULL) {
6554        DEBUG_PRINT_ERROR("\n FATAL ERROR in omx_vdec::async_message_process NULL Check");
6555        return -1;
6556    }
6557
6558    vdec_msg = (struct vdec_msginfo *)message;
6559
6560    omx = reinterpret_cast<omx_vdec*>(context);
6561
6562#ifdef _ANDROID_
6563
6564    if (omx->m_debug_timestamp) {
6565        if ( (vdec_msg->msgcode == VDEC_MSG_RESP_OUTPUT_BUFFER_DONE) &&
6566                !(omx->output_flush_progress) ) {
6567            OMX_TICKS expected_ts = 0;
6568            omx->m_timestamp_list.pop_min_ts(expected_ts);
6569            DEBUG_PRINT_LOW("Current timestamp (%lld),Popped TIMESTAMP (%lld) from list",
6570                    vdec_msg->msgdata.output_frame.time_stamp, expected_ts);
6571
6572            if (vdec_msg->msgdata.output_frame.time_stamp != expected_ts) {
6573                DEBUG_PRINT_ERROR("\n ERROR in omx_vdec::async_message_process timestamp Check");
6574            }
6575        }
6576    }
6577
6578#endif
6579
6580    switch (vdec_msg->msgcode) {
6581
6582        case VDEC_MSG_EVT_HW_ERROR:
6583            omx->post_event (NULL,vdec_msg->status_code,\
6584                    OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6585            break;
6586
6587        case VDEC_MSG_RESP_START_DONE:
6588            omx->post_event (NULL,vdec_msg->status_code,\
6589                    OMX_COMPONENT_GENERATE_START_DONE);
6590            break;
6591
6592        case VDEC_MSG_RESP_STOP_DONE:
6593            omx->post_event (NULL,vdec_msg->status_code,\
6594                    OMX_COMPONENT_GENERATE_STOP_DONE);
6595            break;
6596
6597        case VDEC_MSG_RESP_RESUME_DONE:
6598            omx->post_event (NULL,vdec_msg->status_code,\
6599                    OMX_COMPONENT_GENERATE_RESUME_DONE);
6600            break;
6601
6602        case VDEC_MSG_RESP_PAUSE_DONE:
6603            omx->post_event (NULL,vdec_msg->status_code,\
6604                    OMX_COMPONENT_GENERATE_PAUSE_DONE);
6605            break;
6606
6607        case VDEC_MSG_RESP_FLUSH_INPUT_DONE:
6608            omx->post_event (NULL,vdec_msg->status_code,\
6609                    OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH);
6610            break;
6611        case VDEC_MSG_RESP_FLUSH_OUTPUT_DONE:
6612            omx->post_event (NULL,vdec_msg->status_code,\
6613                    OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH);
6614            break;
6615        case VDEC_MSG_RESP_INPUT_FLUSHED:
6616        case VDEC_MSG_RESP_INPUT_BUFFER_DONE:
6617
6618            omxhdr = (OMX_BUFFERHEADERTYPE* )\
6619                     vdec_msg->msgdata.input_frame_clientdata;
6620
6621
6622            if (omxhdr == NULL ||
6623                    ((omxhdr - omx->m_inp_mem_ptr) > omx->drv_ctx.ip_buf.actualcount) ) {
6624                omxhdr = NULL;
6625                vdec_msg->status_code = VDEC_S_EFATAL;
6626            }
6627
6628            omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6629                    OMX_COMPONENT_GENERATE_EBD);
6630            break;
6631        case VDEC_MSG_EVT_INFO_FIELD_DROPPED:
6632            int64_t *timestamp;
6633            timestamp = (int64_t *) malloc(sizeof(int64_t));
6634
6635            if (timestamp) {
6636                *timestamp = vdec_msg->msgdata.output_frame.time_stamp;
6637                omx->post_event ((unsigned int)timestamp, vdec_msg->status_code,
6638                        OMX_COMPONENT_GENERATE_INFO_FIELD_DROPPED);
6639                DEBUG_PRINT_HIGH("Field dropped time stamp is %lld",
6640                        vdec_msg->msgdata.output_frame.time_stamp);
6641            }
6642
6643            break;
6644        case VDEC_MSG_RESP_OUTPUT_FLUSHED:
6645        case VDEC_MSG_RESP_OUTPUT_BUFFER_DONE:
6646            omxhdr = (OMX_BUFFERHEADERTYPE*)vdec_msg->msgdata.output_frame.client_data;
6647            DEBUG_PRINT_LOW("[RespBufDone] Buf(%p) Ts(%lld) Pic_type(%u)",
6648                    omxhdr, vdec_msg->msgdata.output_frame.time_stamp,
6649                    vdec_msg->msgdata.output_frame.pic_type);
6650
6651            /* update SYNCFRAME flag */
6652            if (omx->eCompressionFormat == OMX_VIDEO_CodingAVC) {
6653                /* set SYNCFRAME flag if picture type is IDR for h264 */
6654                if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_IDR)
6655                    vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME;
6656                else
6657                    vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6658            } else {
6659                /* set SYNCFRAME flag if picture type is I_TYPE */
6660                if (vdec_msg->msgdata.output_frame.pic_type == PICTURE_TYPE_I)
6661                    vdec_msg->msgdata.output_frame.flags |= OMX_BUFFERFLAG_SYNCFRAME;
6662                else
6663                    vdec_msg->msgdata.output_frame.flags &= ~OMX_BUFFERFLAG_SYNCFRAME;
6664            }
6665
6666            if (omxhdr && omxhdr->pOutputPortPrivate &&
6667                    ((omxhdr - omx->m_out_mem_ptr) < omx->drv_ctx.op_buf.actualcount) &&
6668                    (((struct vdec_output_frameinfo *)omxhdr->pOutputPortPrivate
6669                      - omx->drv_ctx.ptr_respbuffer) < omx->drv_ctx.op_buf.actualcount)) {
6670                if (vdec_msg->msgdata.output_frame.len <=  omxhdr->nAllocLen) {
6671                    omxhdr->nFilledLen = vdec_msg->msgdata.output_frame.len;
6672                    omxhdr->nOffset = vdec_msg->msgdata.output_frame.offset;
6673                    omxhdr->nTimeStamp = vdec_msg->msgdata.output_frame.time_stamp;
6674                    omxhdr->nFlags = (vdec_msg->msgdata.output_frame.flags);
6675
6676                    output_respbuf = (struct vdec_output_frameinfo *)\
6677                                     omxhdr->pOutputPortPrivate;
6678                    output_respbuf->framesize.bottom =
6679                        vdec_msg->msgdata.output_frame.framesize.bottom;
6680                    output_respbuf->framesize.left =
6681                        vdec_msg->msgdata.output_frame.framesize.left;
6682                    output_respbuf->framesize.right =
6683                        vdec_msg->msgdata.output_frame.framesize.right;
6684                    output_respbuf->framesize.top =
6685                        vdec_msg->msgdata.output_frame.framesize.top;
6686                    output_respbuf->len = vdec_msg->msgdata.output_frame.len;
6687                    output_respbuf->offset = vdec_msg->msgdata.output_frame.offset;
6688                    output_respbuf->time_stamp = vdec_msg->msgdata.output_frame.time_stamp;
6689                    output_respbuf->flags = vdec_msg->msgdata.output_frame.flags;
6690                    output_respbuf->pic_type = vdec_msg->msgdata.output_frame.pic_type;
6691                    output_respbuf->interlaced_format = vdec_msg->msgdata.output_frame.interlaced_format;
6692                    output_respbuf->aspect_ratio_info =
6693                        vdec_msg->msgdata.output_frame.aspect_ratio_info;
6694
6695                    if (omx->output_use_buffer)
6696                        memcpy ( omxhdr->pBuffer,
6697                                (vdec_msg->msgdata.output_frame.bufferaddr +
6698                                 vdec_msg->msgdata.output_frame.offset),
6699                                vdec_msg->msgdata.output_frame.len );
6700                } else
6701                    omxhdr->nFilledLen = 0;
6702
6703                omx->post_event ((unsigned int)omxhdr, vdec_msg->status_code,
6704                        OMX_COMPONENT_GENERATE_FBD);
6705            } else if (vdec_msg->msgdata.output_frame.flags & OMX_BUFFERFLAG_EOS)
6706                omx->post_event (NULL, vdec_msg->status_code,
6707                        OMX_COMPONENT_GENERATE_EOS_DONE);
6708            else
6709                omx->post_event (NULL, vdec_msg->status_code,
6710                        OMX_COMPONENT_GENERATE_HARDWARE_ERROR);
6711
6712            break;
6713        case VDEC_MSG_EVT_CONFIG_CHANGED:
6714            DEBUG_PRINT_HIGH("Port settings changed");
6715            omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6716                    OMX_COMPONENT_GENERATE_PORT_RECONFIG);
6717            break;
6718        case VDEC_MSG_EVT_INFO_CONFIG_CHANGED:
6719            {
6720                DEBUG_PRINT_HIGH("Port settings changed info");
6721                // get_buffer_req and populate port defn structure
6722                OMX_ERRORTYPE eRet = OMX_ErrorNone;
6723                omx->m_port_def.nPortIndex = 1;
6724                eRet = omx->update_portdef(&(omx->m_port_def));
6725                omx->post_event ((unsigned int)omxhdr,vdec_msg->status_code,
6726                        OMX_COMPONENT_GENERATE_INFO_PORT_RECONFIG);
6727                break;
6728            }
6729        default:
6730            break;
6731    }
6732
6733    return 1;
6734}
6735
6736OMX_ERRORTYPE omx_vdec::empty_this_buffer_proxy_arbitrary (
6737        OMX_HANDLETYPE hComp,
6738        OMX_BUFFERHEADERTYPE *buffer
6739        )
6740{
6741    unsigned address,p2,id;
6742    DEBUG_PRINT_LOW("Empty this arbitrary");
6743
6744    if (buffer == NULL) {
6745        return OMX_ErrorBadParameter;
6746    }
6747
6748    DEBUG_PRINT_LOW("ETBProxyArb: bufhdr = %p, bufhdr->pBuffer = %p", buffer, buffer->pBuffer);
6749    DEBUG_PRINT_LOW("ETBProxyArb: nFilledLen %u, flags %d, timestamp %u",
6750            buffer->nFilledLen, buffer->nFlags, (unsigned)buffer->nTimeStamp);
6751
6752    /* return zero length and not an EOS buffer */
6753
6754    /* return buffer if input flush in progress */
6755    if ((input_flush_progress == true) || ((buffer->nFilledLen == 0) &&
6756                ((buffer->nFlags & OMX_BUFFERFLAG_EOS) == 0))) {
6757        DEBUG_PRINT_HIGH("return zero legth buffer or flush in progress");
6758        m_cb.EmptyBufferDone (hComp,m_app_data,buffer);
6759        return OMX_ErrorNone;
6760    }
6761
6762    if (psource_frame == NULL) {
6763        DEBUG_PRINT_LOW("Set Buffer as source Buffer %p time stamp %d",buffer,buffer->nTimeStamp);
6764        psource_frame = buffer;
6765        DEBUG_PRINT_LOW("Try to Push One Input Buffer ");
6766        push_input_buffer (hComp);
6767    } else {
6768        DEBUG_PRINT_LOW("Push the source buffer into pendingq %p",buffer);
6769
6770        if (!m_input_pending_q.insert_entry((unsigned)buffer,NULL,NULL)) {
6771            return OMX_ErrorBadParameter;
6772        }
6773    }
6774
6775
6776    return OMX_ErrorNone;
6777}
6778
6779OMX_ERRORTYPE omx_vdec::push_input_buffer (OMX_HANDLETYPE hComp)
6780{
6781    unsigned address,p2,id;
6782    OMX_ERRORTYPE ret = OMX_ErrorNone;
6783
6784    if (pdest_frame == NULL || psource_frame == NULL) {
6785        /*Check if we have a destination buffer*/
6786        if (pdest_frame == NULL) {
6787            DEBUG_PRINT_LOW("Get a Destination buffer from the queue");
6788
6789            if (m_input_free_q.m_size) {
6790                m_input_free_q.pop_entry(&address,&p2,&id);
6791                pdest_frame = (OMX_BUFFERHEADERTYPE *)address;
6792                pdest_frame->nFilledLen = 0;
6793                pdest_frame->nTimeStamp = LLONG_MAX;
6794                DEBUG_PRINT_LOW("Address of Pmem Buffer %p",pdest_frame);
6795            }
6796        }
6797
6798        /*Check if we have a destination buffer*/
6799        if (psource_frame == NULL) {
6800            DEBUG_PRINT_LOW("Get a source buffer from the queue");
6801
6802            if (m_input_pending_q.m_size) {
6803                m_input_pending_q.pop_entry(&address,&p2,&id);
6804                psource_frame = (OMX_BUFFERHEADERTYPE *)address;
6805                DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame,
6806                        psource_frame->nTimeStamp);
6807                DEBUG_PRINT_LOW("Next source Buffer flag %d length %d",
6808                        psource_frame->nFlags,psource_frame->nFilledLen);
6809
6810            }
6811        }
6812
6813    }
6814
6815    while ((pdest_frame != NULL) && (psource_frame != NULL)) {
6816        switch (codec_type_parse) {
6817            case CODEC_TYPE_MPEG4:
6818            case CODEC_TYPE_H263:
6819            case CODEC_TYPE_MPEG2:
6820                ret =  push_input_sc_codec(hComp);
6821                break;
6822            case CODEC_TYPE_H264:
6823                ret = push_input_h264(hComp);
6824                break;
6825            case CODEC_TYPE_VC1:
6826                ret = push_input_vc1(hComp);
6827                break;
6828        }
6829
6830        if (ret != OMX_ErrorNone) {
6831            DEBUG_PRINT_ERROR("\n Pushing input Buffer Failed");
6832            omx_report_error ();
6833            break;
6834        }
6835    }
6836
6837    return ret;
6838}
6839
6840OMX_ERRORTYPE omx_vdec::push_input_sc_codec(OMX_HANDLETYPE hComp)
6841{
6842    OMX_U32 partial_frame = 1;
6843    OMX_BOOL generate_ebd = OMX_TRUE;
6844    unsigned address,p2,id;
6845
6846    DEBUG_PRINT_LOW("Start Parsing the bit stream address %p TimeStamp %d",
6847            psource_frame,psource_frame->nTimeStamp);
6848
6849    if (m_frame_parser.parse_sc_frame(psource_frame,
6850                pdest_frame,&partial_frame) == -1) {
6851        DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6852        return OMX_ErrorBadParameter;
6853    }
6854
6855    if (partial_frame == 0) {
6856        DEBUG_PRINT_LOW("Frame size %d source %p frame count %d",
6857                pdest_frame->nFilledLen,psource_frame,frame_count);
6858
6859
6860        DEBUG_PRINT_LOW("TimeStamp updated %d",pdest_frame->nTimeStamp);
6861
6862        /*First Parsed buffer will have only header Hence skip*/
6863        if (frame_count == 0) {
6864            DEBUG_PRINT_LOW("H263/MPEG4 Codec First Frame ");
6865#ifdef MAX_RES_1080P
6866
6867            if (codec_type_parse == CODEC_TYPE_MPEG4 ||
6868                    codec_type_parse == CODEC_TYPE_DIVX) {
6869                mp4StreamType psBits;
6870                psBits.data = pdest_frame->pBuffer + pdest_frame->nOffset;
6871                psBits.numBytes = pdest_frame->nFilledLen;
6872                mp4_headerparser.parseHeader(&psBits);
6873            }
6874
6875#endif
6876            frame_count++;
6877        } else {
6878            pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
6879
6880            if (pdest_frame->nFilledLen) {
6881                /*Push the frame to the Decoder*/
6882                if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6883                    return OMX_ErrorBadParameter;
6884                }
6885
6886                frame_count++;
6887                pdest_frame = NULL;
6888
6889                if (m_input_free_q.m_size) {
6890                    m_input_free_q.pop_entry(&address,&p2,&id);
6891                    pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
6892                    pdest_frame->nFilledLen = 0;
6893                }
6894            } else if (!(psource_frame->nFlags & OMX_BUFFERFLAG_EOS)) {
6895                DEBUG_PRINT_ERROR("\nZero len buffer return back to POOL");
6896                m_input_free_q.insert_entry((unsigned) pdest_frame,NULL,NULL);
6897                pdest_frame = NULL;
6898            }
6899        }
6900    } else {
6901        DEBUG_PRINT_LOW("Not a Complete Frame %d",pdest_frame->nFilledLen);
6902
6903        /*Check if Destination Buffer is full*/
6904        if (pdest_frame->nAllocLen ==
6905                pdest_frame->nFilledLen + pdest_frame->nOffset) {
6906            DEBUG_PRINT_ERROR("\nERROR:Frame Not found though Destination Filled");
6907            return OMX_ErrorStreamCorrupt;
6908        }
6909    }
6910
6911    if (psource_frame->nFilledLen == 0) {
6912        if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
6913            if (pdest_frame) {
6914                pdest_frame->nFlags |= psource_frame->nFlags;
6915                DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x",
6916                        pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
6917                DEBUG_PRINT_LOW("Found a frame size = %d number = %d",
6918                        pdest_frame->nFilledLen,frame_count++);
6919
6920                /*Push the frame to the Decoder*/
6921                if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
6922                    return OMX_ErrorBadParameter;
6923                }
6924
6925                frame_count++;
6926                pdest_frame = NULL;
6927            } else {
6928                DEBUG_PRINT_LOW("Last frame in else dest addr") ;
6929                generate_ebd = OMX_FALSE;
6930            }
6931        }
6932
6933        if (generate_ebd) {
6934            DEBUG_PRINT_LOW("Buffer Consumed return back to client %p",psource_frame);
6935            m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
6936            psource_frame = NULL;
6937
6938            if (m_input_pending_q.m_size) {
6939                DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
6940                m_input_pending_q.pop_entry(&address,&p2,&id);
6941                psource_frame = (OMX_BUFFERHEADERTYPE *) address;
6942                DEBUG_PRINT_LOW("Next source Buffer %p time stamp %d",psource_frame,
6943                        psource_frame->nTimeStamp);
6944                DEBUG_PRINT_LOW("Next source Buffer flag %d length %d",
6945                        psource_frame->nFlags,psource_frame->nFilledLen);
6946            }
6947        }
6948    }
6949
6950    return OMX_ErrorNone;
6951}
6952
6953OMX_ERRORTYPE omx_vdec::push_input_h264 (OMX_HANDLETYPE hComp)
6954{
6955    OMX_U32 partial_frame = 1;
6956    unsigned address,p2,id;
6957    OMX_BOOL isNewFrame = OMX_FALSE;
6958    OMX_BOOL generate_ebd = OMX_TRUE;
6959
6960    if (h264_scratch.pBuffer == NULL) {
6961        DEBUG_PRINT_ERROR("\nERROR:H.264 Scratch Buffer not allocated");
6962        return OMX_ErrorBadParameter;
6963    }
6964
6965    DEBUG_PRINT_LOW("Pending h264_scratch.nFilledLen %d "
6966            "look_ahead_nal %d", h264_scratch.nFilledLen, look_ahead_nal);
6967    DEBUG_PRINT_LOW("Pending pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
6968
6969    if (h264_scratch.nFilledLen && look_ahead_nal) {
6970        look_ahead_nal = false;
6971
6972        if ((pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
6973                h264_scratch.nFilledLen) {
6974            memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
6975                    h264_scratch.pBuffer,h264_scratch.nFilledLen);
6976            pdest_frame->nFilledLen += h264_scratch.nFilledLen;
6977            DEBUG_PRINT_LOW("Copy the previous NAL (h264 scratch) into Dest frame");
6978            h264_scratch.nFilledLen = 0;
6979        } else {
6980            DEBUG_PRINT_ERROR("\n Error:1: Destination buffer overflow for H264");
6981            return OMX_ErrorBadParameter;
6982        }
6983    }
6984
6985    if (nal_length == 0) {
6986        DEBUG_PRINT_LOW("Zero NAL, hence parse using start code");
6987
6988        if (m_frame_parser.parse_sc_frame(psource_frame,
6989                    &h264_scratch,&partial_frame) == -1) {
6990            DEBUG_PRINT_ERROR("\n Error In Parsing Return Error");
6991            return OMX_ErrorBadParameter;
6992        }
6993    } else {
6994        DEBUG_PRINT_LOW("Non-zero NAL length clip, hence parse with NAL size %d ",nal_length);
6995
6996        if (m_frame_parser.parse_h264_nallength(psource_frame,
6997                    &h264_scratch,&partial_frame) == -1) {
6998            DEBUG_PRINT_ERROR("\n Error In Parsing NAL size, Return Error");
6999            return OMX_ErrorBadParameter;
7000        }
7001    }
7002
7003    if (partial_frame == 0) {
7004        if (nal_count == 0 && h264_scratch.nFilledLen == 0) {
7005            DEBUG_PRINT_LOW("First NAL with Zero Length, hence Skip");
7006            nal_count++;
7007            h264_scratch.nTimeStamp = psource_frame->nTimeStamp;
7008            h264_scratch.nFlags = psource_frame->nFlags;
7009        } else {
7010            DEBUG_PRINT_LOW("Parsed New NAL Length = %d",h264_scratch.nFilledLen);
7011
7012            if (h264_scratch.nFilledLen) {
7013                h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer, h264_scratch.nFilledLen,
7014                        NALU_TYPE_SPS);
7015#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7016
7017                if (client_extradata & OMX_TIMEINFO_EXTRADATA)
7018                    h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7019                            h264_scratch.nFilledLen, NALU_TYPE_SEI);
7020                else if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7021                    // If timeinfo is present frame info from SEI is already processed
7022                    h264_parser->parse_nal((OMX_U8*)h264_scratch.pBuffer,
7023                            h264_scratch.nFilledLen, NALU_TYPE_SEI);
7024
7025#endif
7026                m_frame_parser.mutils->isNewFrame(&h264_scratch, 0, isNewFrame);
7027                nal_count++;
7028
7029                if (VALID_TS(h264_last_au_ts) && !VALID_TS(pdest_frame->nTimeStamp)) {
7030                    pdest_frame->nTimeStamp = h264_last_au_ts;
7031                    pdest_frame->nFlags = h264_last_au_flags;
7032#ifdef PANSCAN_HDLR
7033
7034                    if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
7035                        h264_parser->update_panscan_data(h264_last_au_ts);
7036
7037#endif
7038                }
7039
7040                if (m_frame_parser.mutils->nalu_type == NALU_TYPE_NON_IDR ||
7041                        m_frame_parser.mutils->nalu_type == NALU_TYPE_IDR) {
7042                    h264_last_au_ts = h264_scratch.nTimeStamp;
7043                    h264_last_au_flags = h264_scratch.nFlags;
7044#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7045
7046                    if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7047                        OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(h264_last_au_ts);
7048
7049                        if (!VALID_TS(h264_last_au_ts))
7050                            h264_last_au_ts = ts_in_sei;
7051                    }
7052
7053#endif
7054                } else
7055                    h264_last_au_ts = LLONG_MAX;
7056            }
7057
7058            if (!isNewFrame) {
7059                if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7060                        h264_scratch.nFilledLen) {
7061                    DEBUG_PRINT_LOW("Not a NewFrame Copy into Dest len %d",
7062                            h264_scratch.nFilledLen);
7063                    memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7064                            h264_scratch.pBuffer,h264_scratch.nFilledLen);
7065                    pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7066
7067                    if (m_frame_parser.mutils->nalu_type == NALU_TYPE_EOSEQ)
7068                        pdest_frame->nFlags |= QOMX_VIDEO_BUFFERFLAG_EOSEQ;
7069
7070                    h264_scratch.nFilledLen = 0;
7071                } else {
7072                    DEBUG_PRINT_ERROR("\n Error:2: Destination buffer overflow for H264");
7073                    return OMX_ErrorBadParameter;
7074                }
7075            } else {
7076                look_ahead_nal = true;
7077                DEBUG_PRINT_LOW("Frame Found start Decoding Size =%d TimeStamp = %x",
7078                        pdest_frame->nFilledLen,pdest_frame->nTimeStamp);
7079                DEBUG_PRINT_LOW("Found a frame size = %d number = %d",
7080                        pdest_frame->nFilledLen,frame_count++);
7081
7082                if (pdest_frame->nFilledLen == 0) {
7083                    DEBUG_PRINT_LOW("Copy the Current Frame since and push it");
7084                    look_ahead_nal = false;
7085
7086                    if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7087                            h264_scratch.nFilledLen) {
7088                        memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7089                                h264_scratch.pBuffer,h264_scratch.nFilledLen);
7090                        pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7091                        h264_scratch.nFilledLen = 0;
7092                    } else {
7093                        DEBUG_PRINT_ERROR("\n Error:3: Destination buffer overflow for H264");
7094                        return OMX_ErrorBadParameter;
7095                    }
7096                } else {
7097                    if (psource_frame->nFilledLen || h264_scratch.nFilledLen) {
7098                        DEBUG_PRINT_LOW("Reset the EOS Flag");
7099                        pdest_frame->nFlags &= ~OMX_BUFFERFLAG_EOS;
7100                    }
7101
7102                    /*Push the frame to the Decoder*/
7103                    if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7104                        return OMX_ErrorBadParameter;
7105                    }
7106
7107                    //frame_count++;
7108                    pdest_frame = NULL;
7109
7110                    if (m_input_free_q.m_size) {
7111                        m_input_free_q.pop_entry(&address,&p2,&id);
7112                        pdest_frame = (OMX_BUFFERHEADERTYPE *) address;
7113                        DEBUG_PRINT_LOW("Pop the next pdest_buffer %p",pdest_frame);
7114                        pdest_frame->nFilledLen = 0;
7115                        pdest_frame->nFlags = 0;
7116                        pdest_frame->nTimeStamp = LLONG_MAX;
7117                    }
7118                }
7119            }
7120        }
7121    } else {
7122        DEBUG_PRINT_LOW("Not a Complete Frame, pdest_frame->nFilledLen %d",pdest_frame->nFilledLen);
7123
7124        /*Check if Destination Buffer is full*/
7125        if (h264_scratch.nAllocLen ==
7126                h264_scratch.nFilledLen + h264_scratch.nOffset) {
7127            DEBUG_PRINT_ERROR("\nERROR: Frame Not found though Destination Filled");
7128            return OMX_ErrorStreamCorrupt;
7129        }
7130    }
7131
7132    if (!psource_frame->nFilledLen) {
7133        DEBUG_PRINT_LOW("Buffer Consumed return source %p back to client",psource_frame);
7134
7135        if (psource_frame->nFlags & OMX_BUFFERFLAG_EOS) {
7136            if (pdest_frame) {
7137                DEBUG_PRINT_LOW("EOS Reached Pass Last Buffer");
7138
7139                if ( (pdest_frame->nAllocLen - pdest_frame->nFilledLen) >=
7140                        h264_scratch.nFilledLen) {
7141                    memcpy ((pdest_frame->pBuffer + pdest_frame->nFilledLen),
7142                            h264_scratch.pBuffer,h264_scratch.nFilledLen);
7143                    pdest_frame->nFilledLen += h264_scratch.nFilledLen;
7144                    h264_scratch.nFilledLen = 0;
7145                } else {
7146                    DEBUG_PRINT_ERROR("\nERROR:4: Destination buffer overflow for H264");
7147                    return OMX_ErrorBadParameter;
7148                }
7149
7150                pdest_frame->nTimeStamp = h264_scratch.nTimeStamp;
7151                pdest_frame->nFlags = h264_scratch.nFlags | psource_frame->nFlags;
7152#ifdef MAX_RES_720P
7153
7154                if (frame_count == 0) {
7155                    DEBUG_PRINT_HIGH("No frames sent to driver yet, "
7156                            "So send zero length EOS buffer");
7157                    pdest_frame->nFilledLen = 0;
7158                }
7159
7160#endif
7161                DEBUG_PRINT_LOW("pdest_frame->nFilledLen = %d, nFlags = 0x%x, TimeStamp = %x",
7162                        pdest_frame->nFilledLen, pdest_frame->nFlags, pdest_frame->nTimeStamp);
7163                DEBUG_PRINT_LOW("Push AU frame number %d to driver", frame_count++);
7164#ifndef PROCESS_EXTRADATA_IN_OUTPUT_PORT
7165
7166                if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
7167                    OMX_S64 ts_in_sei = h264_parser->process_ts_with_sei_vui(pdest_frame->nTimeStamp);
7168
7169                    if (!VALID_TS(pdest_frame->nTimeStamp))
7170                        pdest_frame->nTimeStamp = ts_in_sei;
7171                }
7172
7173#endif
7174
7175                /*Push the frame to the Decoder*/
7176                if (empty_this_buffer_proxy(hComp,pdest_frame) != OMX_ErrorNone) {
7177                    return OMX_ErrorBadParameter;
7178                }
7179
7180                frame_count++;
7181                pdest_frame = NULL;
7182            } else {
7183                DEBUG_PRINT_LOW("Last frame in else dest addr %p size %d",
7184                        pdest_frame,h264_scratch.nFilledLen);
7185                generate_ebd = OMX_FALSE;
7186            }
7187        }
7188    }
7189
7190    if (generate_ebd && !psource_frame->nFilledLen) {
7191        m_cb.EmptyBufferDone (hComp,m_app_data,psource_frame);
7192        psource_frame = NULL;
7193
7194        if (m_input_pending_q.m_size) {
7195            DEBUG_PRINT_LOW("Pull Next source Buffer %p",psource_frame);
7196            m_input_pending_q.pop_entry(&address,&p2,&id);
7197            psource_frame = (OMX_BUFFERHEADERTYPE *) address;
7198            DEBUG_PRINT_LOW("Next source Buffer flag %d src length %d",
7199                    psource_frame->nFlags,psource_frame->nFilledLen);
7200        }
7201    }
7202
7203    return OMX_ErrorNone;
7204}
7205
7206OMX_ERRORTYPE omx_vdec::push_input_vc1 (OMX_HANDLETYPE hComp)
7207{
7208    OMX_U8 *buf, *pdest;
7209    OMX_U32 partial_frame = 1;
7210    OMX_U32 buf_len, dest_len;
7211
7212    if (first_frame == 0) {
7213        first_frame = 1;
7214        DEBUG_PRINT_LOW("First i/p buffer for VC1 arbitrary bytes");
7215
7216        if (!m_vendor_config.pData) {
7217            DEBUG_PRINT_LOW("Check profile type in 1st source buffer");
7218            buf = psource_frame->pBuffer;
7219            buf_len = psource_frame->nFilledLen;
7220
7221            if ((*((OMX_U32 *) buf) & VC1_SP_MP_START_CODE_MASK) ==
7222                    VC1_SP_MP_START_CODE) {
7223                m_vc1_profile = VC1_SP_MP_RCV;
7224            } else if (*((OMX_U32 *) buf) & VC1_AP_SEQ_START_CODE) {
7225                m_vc1_profile = VC1_AP;
7226            } else {
7227                DEBUG_PRINT_ERROR("\nInvalid sequence layer in first buffer");
7228                return OMX_ErrorStreamCorrupt;
7229            }
7230        } else {
7231            pdest = pdest_frame->pBuffer + pdest_frame->nFilledLen +
7232                pdest_frame->nOffset;
7233            dest_len = pdest_frame->nAllocLen - (pdest_frame->nFilledLen +
7234                    pdest_frame->nOffset);
7235
7236            if (dest_len < m_vendor_config.nDataSize) {
7237                DEBUG_PRINT_ERROR("\nDestination buffer full");
7238                return OMX_ErrorBadParameter;
7239            } else {
7240                memcpy(pdest, m_vendor_config.pData, m_vendor_config.nDataSize);
7241                pdest_frame->nFilledLen += m_vendor_config.nDataSize;
7242            }
7243        }
7244    }
7245
7246    switch (m_vc1_profile) {
7247        case VC1_AP:
7248            DEBUG_PRINT_LOW("VC1 AP, hence parse using frame start code");
7249
7250            if (push_input_sc_codec(hComp) != OMX_ErrorNone) {
7251                DEBUG_PRINT_ERROR("\n Error In Parsing VC1 AP start code");
7252                return OMX_ErrorBadParameter;
7253            }
7254
7255            break;
7256
7257        case VC1_SP_MP_RCV:
7258        default:
7259            DEBUG_PRINT_ERROR("\n Unsupported VC1 profile in ArbitraryBytes Mode");
7260            return OMX_ErrorBadParameter;
7261    }
7262
7263    return OMX_ErrorNone;
7264}
7265
7266#ifndef USE_ION
7267bool omx_vdec::align_pmem_buffers(int pmem_fd, OMX_U32 buffer_size,
7268        OMX_U32 alignment)
7269{
7270    struct pmem_allocation allocation;
7271    allocation.size = buffer_size;
7272    allocation.align = clip2(alignment);
7273
7274    if (allocation.align < 4096) {
7275        allocation.align = 4096;
7276    }
7277
7278    if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
7279        DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
7280                allocation.align, allocation.size);
7281        return false;
7282    }
7283
7284    return true;
7285}
7286#endif
7287
7288#ifdef USE_ION
7289int omx_vdec::alloc_map_ion_memory(OMX_U32 buffer_size,
7290        OMX_U32 alignment, struct ion_allocation_data *alloc_data,
7291        struct ion_fd_data *fd_data,int flag)
7292{
7293    int fd = -EINVAL;
7294    int rc = -EINVAL;
7295    int ion_dev_flag;
7296    struct vdec_ion ion_buf_info;
7297
7298    if (!alloc_data || buffer_size <= 0 || !fd_data) {
7299        DEBUG_PRINT_ERROR("Invalid arguments to alloc_map_ion_memory\n");
7300        return -EINVAL;
7301    }
7302
7303    ion_dev_flag = O_RDONLY;
7304    fd = open (MEM_DEVICE, ion_dev_flag);
7305
7306    if (fd < 0) {
7307        DEBUG_PRINT_ERROR("opening ion device failed with fd = %d\n", fd);
7308        return fd;
7309    }
7310
7311    alloc_data->flags = 0;
7312
7313    if (!secure_mode && (flag & ION_FLAG_CACHED)) {
7314        alloc_data->flags |= ION_FLAG_CACHED;
7315    }
7316
7317    alloc_data->len = buffer_size;
7318    alloc_data->align = clip2(alignment);
7319
7320    if (alloc_data->align < 4096) {
7321        alloc_data->align = 4096;
7322    }
7323
7324    if (secure_mode) {
7325        if (external_meta_buffer) {
7326            alloc_data->heap_mask = ION_HEAP(ION_CP_MFC_HEAP_ID);
7327            alloc_data->flags |= ION_SECURE;
7328        } else if (external_meta_buffer_iommu) {
7329            alloc_data->heap_mask = ION_HEAP(ION_IOMMU_HEAP_ID);
7330        } else {
7331            alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7332            alloc_data->flags |= ION_SECURE;
7333        }
7334    } else {
7335#ifdef MAX_RES_720P
7336        alloc_data->len = (buffer_size + (alloc_data->align - 1)) & ~(alloc_data->align - 1);
7337        alloc_data->heap_mask = ION_HEAP(MEM_HEAP_ID);
7338#else
7339        alloc_data->heap_mask = (ION_HEAP(MEM_HEAP_ID) | ION_HEAP(ION_IOMMU_HEAP_ID));
7340#endif
7341    }
7342
7343    rc = ioctl(fd,ION_IOC_ALLOC,alloc_data);
7344
7345    if (rc || !alloc_data->handle) {
7346        DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
7347        alloc_data->handle = NULL;
7348        close(fd);
7349        fd = -ENOMEM;
7350        return fd;
7351    }
7352
7353    fd_data->handle = alloc_data->handle;
7354    rc = ioctl(fd,ION_IOC_MAP,fd_data);
7355
7356    if (rc) {
7357        DEBUG_PRINT_ERROR("\n ION MAP failed ");
7358        ion_buf_info.ion_alloc_data = *alloc_data;
7359        ion_buf_info.ion_device_fd = fd;
7360        ion_buf_info.fd_ion_data = *fd_data;
7361        free_ion_memory(&ion_buf_info);
7362        fd_data->fd =-1;
7363        close(fd);
7364        fd = -ENOMEM;
7365    }
7366
7367    DEBUG_PRINT_HIGH("ION: alloc_data: handle(0x%X), len(%u), align(%u), "
7368            "flags(0x%x), fd_data: handle(0x%x), fd(0x%x)",
7369            alloc_data->handle, alloc_data->len, alloc_data->align,
7370            alloc_data->flags, fd_data->handle, fd_data->fd);
7371    return fd;
7372}
7373
7374void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
7375{
7376
7377    if (!buf_ion_info) {
7378        DEBUG_PRINT_ERROR("\n ION: free called with invalid fd/allocdata");
7379        return;
7380    }
7381
7382    DEBUG_PRINT_HIGH("ION: free: handle(0x%X), len(%u), fd(0x%x)",
7383            buf_ion_info->ion_alloc_data.handle,
7384            buf_ion_info->ion_alloc_data.len,
7385            buf_ion_info->fd_ion_data.fd);
7386
7387    if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
7388                &buf_ion_info->ion_alloc_data.handle)) {
7389        DEBUG_PRINT_ERROR("\n ION: free failed" );
7390    }
7391
7392    close(buf_ion_info->ion_device_fd);
7393    buf_ion_info->ion_device_fd = -1;
7394    buf_ion_info->ion_alloc_data.handle = NULL;
7395    buf_ion_info->fd_ion_data.fd = -1;
7396}
7397#endif
7398void omx_vdec::free_output_buffer_header()
7399{
7400    DEBUG_PRINT_HIGH("ALL output buffers are freed/released");
7401    output_use_buffer = false;
7402    ouput_egl_buffers = false;
7403
7404    if (m_out_mem_ptr) {
7405        free (m_out_mem_ptr);
7406        m_out_mem_ptr = NULL;
7407    }
7408
7409    if (m_platform_list) {
7410        free(m_platform_list);
7411        m_platform_list = NULL;
7412    }
7413
7414    if (drv_ctx.ptr_respbuffer) {
7415        free (drv_ctx.ptr_respbuffer);
7416        drv_ctx.ptr_respbuffer = NULL;
7417    }
7418
7419    if (drv_ctx.ptr_outputbuffer) {
7420        free (drv_ctx.ptr_outputbuffer);
7421        drv_ctx.ptr_outputbuffer = NULL;
7422    }
7423
7424#ifdef USE_ION
7425
7426    if (drv_ctx.op_buf_ion_info) {
7427        DEBUG_PRINT_LOW("Free o/p ion context");
7428        free(drv_ctx.op_buf_ion_info);
7429        drv_ctx.op_buf_ion_info = NULL;
7430    }
7431
7432#endif
7433}
7434
7435void omx_vdec::free_input_buffer_header()
7436{
7437    input_use_buffer = false;
7438
7439    if (arbitrary_bytes) {
7440        if (m_frame_parser.mutils) {
7441            DEBUG_PRINT_LOW("Free utils parser");
7442            delete (m_frame_parser.mutils);
7443            m_frame_parser.mutils = NULL;
7444        }
7445
7446        if (m_inp_heap_ptr) {
7447            DEBUG_PRINT_LOW("Free input Heap Pointer");
7448            free (m_inp_heap_ptr);
7449            m_inp_heap_ptr = NULL;
7450        }
7451
7452        if (m_phdr_pmem_ptr) {
7453            DEBUG_PRINT_LOW("Free input pmem header Pointer");
7454            free (m_phdr_pmem_ptr);
7455            m_phdr_pmem_ptr = NULL;
7456        }
7457    }
7458
7459    if (m_inp_mem_ptr) {
7460        DEBUG_PRINT_LOW("Free input pmem Pointer area");
7461        free (m_inp_mem_ptr);
7462        m_inp_mem_ptr = NULL;
7463    }
7464
7465    if (drv_ctx.ptr_inputbuffer) {
7466        DEBUG_PRINT_LOW("Free Driver Context pointer");
7467        free (drv_ctx.ptr_inputbuffer);
7468        drv_ctx.ptr_inputbuffer = NULL;
7469    }
7470
7471#ifdef USE_ION
7472
7473    if (drv_ctx.ip_buf_ion_info) {
7474        DEBUG_PRINT_LOW("Free ion context");
7475        free(drv_ctx.ip_buf_ion_info);
7476        drv_ctx.ip_buf_ion_info = NULL;
7477    }
7478
7479#endif
7480}
7481
7482OMX_ERRORTYPE omx_vdec::get_buffer_req(vdec_allocatorproperty *buffer_prop)
7483{
7484    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7485    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7486    unsigned int buf_size = 0, extra_data_size = 0;
7487    DEBUG_PRINT_LOW("GetBufReq IN: ActCnt(%d) Size(%d)",
7488            buffer_prop->actualcount, buffer_prop->buffer_size);
7489    ioctl_msg.in = NULL;
7490    ioctl_msg.out = buffer_prop;
7491
7492    if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_GET_BUFFER_REQ,
7493                (void*)&ioctl_msg) < 0) {
7494        DEBUG_PRINT_ERROR("Requesting buffer requirements failed");
7495        eRet = OMX_ErrorInsufficientResources;
7496    } else {
7497        buf_size = buffer_prop->buffer_size;
7498
7499        if (client_extradata & OMX_FRAMEINFO_EXTRADATA) {
7500            DEBUG_PRINT_HIGH("Frame info extra data enabled!");
7501            extra_data_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
7502        }
7503
7504        if (client_extradata & OMX_INTERLACE_EXTRADATA) {
7505            DEBUG_PRINT_HIGH("Interlace extra data enabled!");
7506            extra_data_size += OMX_INTERLACE_EXTRADATA_SIZE;
7507        }
7508
7509        if (client_extradata & OMX_PORTDEF_EXTRADATA) {
7510            extra_data_size += OMX_PORTDEF_EXTRADATA_SIZE;
7511            DEBUG_PRINT_HIGH("Smooth streaming enabled extra_data_size=%d",
7512                    extra_data_size);
7513        }
7514
7515        if (extra_data_size) {
7516            extra_data_size += sizeof(OMX_OTHER_EXTRADATATYPE); //Space for terminator
7517            buf_size = ((buf_size + 3)&(~3)); //Align extradata start address to 64Bit
7518        }
7519
7520        buf_size += extra_data_size;
7521        buf_size = (buf_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7522        DEBUG_PRINT_LOW("GetBufReq UPDATE: ActCnt(%d) Size(%d) BufSize(%d)",
7523                buffer_prop->actualcount, buffer_prop->buffer_size, buf_size);
7524
7525        if (in_reconfig) // BufReq will be set to driver when port is disabled
7526            buffer_prop->buffer_size = buf_size;
7527        else if (buf_size != buffer_prop->buffer_size) {
7528            buffer_prop->buffer_size = buf_size;
7529            eRet = set_buffer_req(buffer_prop);
7530        }
7531    }
7532
7533    DEBUG_PRINT_LOW("GetBufReq OUT: ActCnt(%d) Size(%d)",
7534            buffer_prop->actualcount, buffer_prop->buffer_size);
7535    return eRet;
7536}
7537
7538OMX_ERRORTYPE omx_vdec::set_buffer_req(vdec_allocatorproperty *buffer_prop)
7539{
7540    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7541    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7542    unsigned buf_size = 0;
7543    DEBUG_PRINT_LOW("SetBufReq IN: ActCnt(%d) Size(%d)",
7544            buffer_prop->actualcount, buffer_prop->buffer_size);
7545    buf_size = (buffer_prop->buffer_size + buffer_prop->alignment - 1)&(~(buffer_prop->alignment - 1));
7546
7547    if (buf_size != buffer_prop->buffer_size) {
7548        DEBUG_PRINT_ERROR("Buffer size alignment error: Requested(%d) Required(%d)",
7549                buffer_prop->buffer_size, buf_size);
7550        eRet = OMX_ErrorBadParameter;
7551    } else {
7552        ioctl_msg.in = buffer_prop;
7553        ioctl_msg.out = NULL;
7554
7555        if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_BUFFER_REQ,
7556                    (void*)&ioctl_msg) < 0) {
7557            DEBUG_PRINT_ERROR("Setting buffer requirements failed");
7558            eRet = OMX_ErrorInsufficientResources;
7559        } else {
7560            if (!client_buffers.update_buffer_req()) {
7561                DEBUG_PRINT_ERROR("Setting c2D buffer requirements failed");
7562                eRet = OMX_ErrorInsufficientResources;
7563            }
7564        }
7565    }
7566
7567    return eRet;
7568}
7569
7570OMX_ERRORTYPE omx_vdec::start_port_reconfig()
7571{
7572    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7573    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7574    eRet = update_picture_resolution();
7575
7576    if (eRet == OMX_ErrorNone) {
7577        ioctl_msg.out = &drv_ctx.interlace;
7578
7579        if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_INTERLACE_FORMAT, &ioctl_msg)) {
7580            DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_INTERLACE_FORMAT");
7581            eRet = OMX_ErrorHardware;
7582        } else {
7583            if (drv_ctx.interlace != VDEC_InterlaceFrameProgressive) {
7584                DEBUG_PRINT_HIGH("Interlace format detected (%x)!", drv_ctx.interlace);
7585                client_extradata |= OMX_INTERLACE_EXTRADATA;
7586            }
7587
7588            in_reconfig = true;
7589            op_buf_rcnfg.buffer_type = VDEC_BUFFER_TYPE_OUTPUT;
7590            eRet = get_buffer_req(&op_buf_rcnfg);
7591        }
7592    }
7593
7594    if (eRet == OMX_ErrorNone) {
7595        //update power HAL with new width, height and bitrate
7596        power_module_deregister();
7597        power_module_register();
7598    }
7599
7600    return eRet;
7601}
7602
7603OMX_ERRORTYPE omx_vdec::update_picture_resolution()
7604{
7605    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7606    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7607    ioctl_msg.in = NULL;
7608    ioctl_msg.out = &drv_ctx.video_resolution;
7609
7610    if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_GET_PICRES, &ioctl_msg)) {
7611        DEBUG_PRINT_ERROR("Error VDEC_IOCTL_GET_PICRES");
7612        eRet = OMX_ErrorHardware;
7613    }
7614
7615    return eRet;
7616}
7617
7618OMX_ERRORTYPE omx_vdec::update_portdef(OMX_PARAM_PORTDEFINITIONTYPE *portDefn)
7619{
7620    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7621
7622    if (!portDefn) {
7623        return OMX_ErrorBadParameter;
7624    }
7625
7626    DEBUG_PRINT_LOW("omx_vdec::update_portdef");
7627    portDefn->nVersion.nVersion = OMX_SPEC_VERSION;
7628    portDefn->nSize = sizeof(portDefn);
7629    portDefn->eDomain    = OMX_PortDomainVideo;
7630
7631    if (drv_ctx.frame_rate.fps_denominator > 0)
7632        portDefn->format.video.xFramerate = drv_ctx.frame_rate.fps_numerator /
7633            drv_ctx.frame_rate.fps_denominator;
7634    else {
7635        DEBUG_PRINT_ERROR("Error: Divide by zero \n");
7636        return OMX_ErrorBadParameter;
7637    }
7638
7639    if (0 == portDefn->nPortIndex) {
7640        portDefn->eDir =  OMX_DirInput;
7641        portDefn->nBufferCountActual = drv_ctx.ip_buf.actualcount;
7642        portDefn->nBufferCountMin    = drv_ctx.ip_buf.mincount;
7643        portDefn->nBufferSize        = drv_ctx.ip_buf.buffer_size - DEVICE_SCRATCH;
7644        portDefn->format.video.eColorFormat = OMX_COLOR_FormatUnused;
7645        portDefn->format.video.eCompressionFormat = eCompressionFormat;
7646        portDefn->bEnabled   = m_inp_bEnabled;
7647        portDefn->bPopulated = m_inp_bPopulated;
7648    } else if (1 == portDefn->nPortIndex) {
7649        portDefn->eDir =  OMX_DirOutput;
7650
7651        if (update_picture_resolution() != OMX_ErrorNone) {
7652            DEBUG_PRINT_ERROR("update_picture_resolution failed \n");
7653            return OMX_ErrorHardware;
7654        }
7655
7656        if (!client_buffers.update_buffer_req()) {
7657            DEBUG_PRINT_ERROR("\n client_buffers.update_buffer_req Failed");
7658            return OMX_ErrorHardware;
7659        }
7660
7661        if (in_reconfig) {
7662            portDefn->nBufferCountActual = op_buf_rcnfg.actualcount;
7663            portDefn->nBufferCountMin    = op_buf_rcnfg.mincount;
7664            portDefn->nBufferSize        = op_buf_rcnfg.buffer_size;
7665        } else {
7666            portDefn->nBufferCountActual = drv_ctx.op_buf.actualcount;
7667            portDefn->nBufferCountMin    = drv_ctx.op_buf.mincount;
7668            portDefn->nBufferSize        = drv_ctx.op_buf.buffer_size;
7669        }
7670
7671        unsigned int buf_size = 0;
7672
7673        if (!client_buffers.get_buffer_req(buf_size)) {
7674            DEBUG_PRINT_ERROR("\n update buffer requirements");
7675            return OMX_ErrorHardware;
7676        }
7677
7678        portDefn->nBufferSize = buf_size;
7679        portDefn->format.video.eCompressionFormat = OMX_VIDEO_CodingUnused;
7680        portDefn->bEnabled   = m_out_bEnabled;
7681        portDefn->bPopulated = m_out_bPopulated;
7682
7683        if (!client_buffers.get_color_format(portDefn->format.video.eColorFormat)) {
7684            DEBUG_PRINT_ERROR("\n Error in getting color format");
7685            return OMX_ErrorHardware;
7686        }
7687    } else {
7688        portDefn->eDir = OMX_DirMax;
7689        DEBUG_PRINT_LOW(" get_parameter: Bad Port idx %d",
7690                (int)portDefn->nPortIndex);
7691        eRet = OMX_ErrorBadPortIndex;
7692    }
7693
7694    portDefn->format.video.nFrameHeight =  drv_ctx.video_resolution.frame_height;
7695    portDefn->format.video.nFrameWidth  =  drv_ctx.video_resolution.frame_width;
7696    portDefn->format.video.nStride = drv_ctx.video_resolution.stride;
7697    portDefn->format.video.nSliceHeight = drv_ctx.video_resolution.scan_lines;
7698    DEBUG_PRINT_LOW("update_portdef: PortIndex = %u, Width = %d Height = %d "
7699            "Stride = %u SliceHeight = %u output format = 0x%x, eColorFormat = 0x%x",
7700            portDefn->nPortIndex,
7701            portDefn->format.video.nFrameHeight,
7702            portDefn->format.video.nFrameWidth,
7703            portDefn->format.video.nStride,
7704            portDefn->format.video.nSliceHeight,
7705            drv_ctx.output_format,
7706            portDefn->format.video.eColorFormat);
7707    return eRet;
7708}
7709
7710OMX_ERRORTYPE omx_vdec::allocate_output_headers()
7711{
7712    OMX_ERRORTYPE eRet = OMX_ErrorNone;
7713    OMX_BUFFERHEADERTYPE *bufHdr = NULL;
7714    unsigned i= 0;
7715
7716    if (!m_out_mem_ptr) {
7717        DEBUG_PRINT_HIGH("Use o/p buffer case - Header List allocation");
7718        int nBufHdrSize        = 0;
7719        int nPlatformEntrySize = 0;
7720        int nPlatformListSize  = 0;
7721        int nPMEMInfoSize = 0;
7722        OMX_QCOM_PLATFORM_PRIVATE_LIST      *pPlatformList;
7723        OMX_QCOM_PLATFORM_PRIVATE_ENTRY     *pPlatformEntry;
7724        OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pPMEMInfo;
7725
7726        DEBUG_PRINT_LOW("Setting First Output Buffer(%d)",
7727                drv_ctx.op_buf.actualcount);
7728        nBufHdrSize        = drv_ctx.op_buf.actualcount *
7729            sizeof(OMX_BUFFERHEADERTYPE);
7730
7731        nPMEMInfoSize      = drv_ctx.op_buf.actualcount *
7732            sizeof(OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO);
7733        nPlatformListSize  = drv_ctx.op_buf.actualcount *
7734            sizeof(OMX_QCOM_PLATFORM_PRIVATE_LIST);
7735        nPlatformEntrySize = drv_ctx.op_buf.actualcount *
7736            sizeof(OMX_QCOM_PLATFORM_PRIVATE_ENTRY);
7737
7738        DEBUG_PRINT_LOW("TotalBufHdr %d BufHdrSize %d PMEM %d PL %d",nBufHdrSize,
7739                sizeof(OMX_BUFFERHEADERTYPE),
7740                nPMEMInfoSize,
7741                nPlatformListSize);
7742        DEBUG_PRINT_LOW("PE %d bmSize %d ",nPlatformEntrySize,
7743                m_out_bm_count);
7744        m_out_mem_ptr = (OMX_BUFFERHEADERTYPE  *)calloc(nBufHdrSize,1);
7745        // Alloc mem for platform specific info
7746        char *pPtr=NULL;
7747        pPtr = (char*) calloc(nPlatformListSize + nPlatformEntrySize +
7748                nPMEMInfoSize,1);
7749        drv_ctx.ptr_outputbuffer = (struct vdec_bufferpayload *) \
7750                                   calloc (sizeof(struct vdec_bufferpayload),
7751                                           drv_ctx.op_buf.actualcount);
7752        drv_ctx.ptr_respbuffer = (struct vdec_output_frameinfo  *)\
7753                                 calloc (sizeof (struct vdec_output_frameinfo),
7754                                         drv_ctx.op_buf.actualcount);
7755#ifdef USE_ION
7756        drv_ctx.op_buf_ion_info = (struct vdec_ion * ) \
7757                                  calloc (sizeof(struct vdec_ion),drv_ctx.op_buf.actualcount);
7758#endif
7759
7760        if (m_out_mem_ptr && pPtr && drv_ctx.ptr_outputbuffer
7761                && drv_ctx.ptr_respbuffer) {
7762            bufHdr          =  m_out_mem_ptr;
7763            m_platform_list = (OMX_QCOM_PLATFORM_PRIVATE_LIST *)(pPtr);
7764            m_platform_entry= (OMX_QCOM_PLATFORM_PRIVATE_ENTRY *)
7765                (((char *) m_platform_list)  + nPlatformListSize);
7766            m_pmem_info     = (OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *)
7767                (((char *) m_platform_entry) + nPlatformEntrySize);
7768            pPlatformList   = m_platform_list;
7769            pPlatformEntry  = m_platform_entry;
7770            pPMEMInfo       = m_pmem_info;
7771
7772            DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p",m_out_mem_ptr);
7773
7774            // Settting the entire storage nicely
7775            DEBUG_PRINT_LOW("bHdr %p OutMem %p PE %p",bufHdr,
7776                    m_out_mem_ptr,pPlatformEntry);
7777            DEBUG_PRINT_LOW(" Pmem Info = %p ",pPMEMInfo);
7778
7779            for (i=0; i < drv_ctx.op_buf.actualcount ; i++) {
7780                bufHdr->nSize              = sizeof(OMX_BUFFERHEADERTYPE);
7781                bufHdr->nVersion.nVersion  = OMX_SPEC_VERSION;
7782                // Set the values when we determine the right HxW param
7783                bufHdr->nAllocLen          = 0;
7784                bufHdr->nFilledLen         = 0;
7785                bufHdr->pAppPrivate        = NULL;
7786                bufHdr->nOutputPortIndex   = OMX_CORE_OUTPUT_PORT_INDEX;
7787                pPlatformEntry->type       = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
7788                pPlatformEntry->entry      = pPMEMInfo;
7789                // Initialize the Platform List
7790                pPlatformList->nEntries    = 1;
7791                pPlatformList->entryList   = pPlatformEntry;
7792                // Keep pBuffer NULL till vdec is opened
7793                bufHdr->pBuffer            = NULL;
7794                pPMEMInfo->offset          =  0;
7795                pPMEMInfo->pmem_fd = 0;
7796                bufHdr->pPlatformPrivate = pPlatformList;
7797                drv_ctx.ptr_outputbuffer[i].pmem_fd = -1;
7798#ifdef USE_ION
7799                drv_ctx.op_buf_ion_info[i].ion_device_fd =-1;
7800#endif
7801                /*Create a mapping between buffers*/
7802                bufHdr->pOutputPortPrivate = &drv_ctx.ptr_respbuffer[i];
7803                drv_ctx.ptr_respbuffer[i].client_data = (void *) \
7804                                                        &drv_ctx.ptr_outputbuffer[i];
7805                // Move the buffer and buffer header pointers
7806                bufHdr++;
7807                pPMEMInfo++;
7808                pPlatformEntry++;
7809                pPlatformList++;
7810            }
7811        } else {
7812            DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]\n",\
7813                    m_out_mem_ptr, pPtr);
7814
7815            if (m_out_mem_ptr) {
7816                free(m_out_mem_ptr);
7817                m_out_mem_ptr = NULL;
7818            }
7819
7820            if (pPtr) {
7821                free(pPtr);
7822                pPtr = NULL;
7823            }
7824
7825            if (drv_ctx.ptr_outputbuffer) {
7826                free(drv_ctx.ptr_outputbuffer);
7827                drv_ctx.ptr_outputbuffer = NULL;
7828            }
7829
7830            if (drv_ctx.ptr_respbuffer) {
7831                free(drv_ctx.ptr_respbuffer);
7832                drv_ctx.ptr_respbuffer = NULL;
7833            }
7834
7835#ifdef USE_ION
7836
7837            if (drv_ctx.op_buf_ion_info) {
7838                DEBUG_PRINT_LOW("Free o/p ion context");
7839                free(drv_ctx.op_buf_ion_info);
7840                drv_ctx.op_buf_ion_info = NULL;
7841            }
7842
7843#endif
7844            eRet =  OMX_ErrorInsufficientResources;
7845        }
7846    } else {
7847        eRet =  OMX_ErrorInsufficientResources;
7848    }
7849
7850    return eRet;
7851}
7852
7853void omx_vdec::complete_pending_buffer_done_cbs()
7854{
7855    unsigned p1;
7856    unsigned p2;
7857    unsigned ident;
7858    omx_cmd_queue tmp_q, pending_bd_q;
7859    pthread_mutex_lock(&m_lock);
7860
7861    // pop all pending GENERATE FDB from ftb queue
7862    while (m_ftb_q.m_size) {
7863        m_ftb_q.pop_entry(&p1,&p2,&ident);
7864
7865        if (ident == OMX_COMPONENT_GENERATE_FBD) {
7866            pending_bd_q.insert_entry(p1,p2,ident);
7867        } else {
7868            tmp_q.insert_entry(p1,p2,ident);
7869        }
7870    }
7871
7872    //return all non GENERATE FDB to ftb queue
7873    while (tmp_q.m_size) {
7874        tmp_q.pop_entry(&p1,&p2,&ident);
7875        m_ftb_q.insert_entry(p1,p2,ident);
7876    }
7877
7878    // pop all pending GENERATE EDB from etb queue
7879    while (m_etb_q.m_size) {
7880        m_etb_q.pop_entry(&p1,&p2,&ident);
7881
7882        if (ident == OMX_COMPONENT_GENERATE_EBD) {
7883            pending_bd_q.insert_entry(p1,p2,ident);
7884        } else {
7885            tmp_q.insert_entry(p1,p2,ident);
7886        }
7887    }
7888
7889    //return all non GENERATE FDB to etb queue
7890    while (tmp_q.m_size) {
7891        tmp_q.pop_entry(&p1,&p2,&ident);
7892        m_etb_q.insert_entry(p1,p2,ident);
7893    }
7894
7895    pthread_mutex_unlock(&m_lock);
7896
7897    // process all pending buffer dones
7898    while (pending_bd_q.m_size) {
7899        pending_bd_q.pop_entry(&p1,&p2,&ident);
7900
7901        switch (ident) {
7902            case OMX_COMPONENT_GENERATE_EBD:
7903
7904                if (empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone) {
7905                    DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
7906                    omx_report_error ();
7907                }
7908
7909                break;
7910
7911            case OMX_COMPONENT_GENERATE_FBD:
7912
7913                if (fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone ) {
7914                    DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
7915                    omx_report_error ();
7916                }
7917
7918                break;
7919        }
7920    }
7921}
7922
7923void omx_vdec::set_frame_rate(OMX_S64 act_timestamp)
7924{
7925    OMX_U32 new_frame_interval = 0;
7926    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
7927
7928    if (VALID_TS(act_timestamp) && VALID_TS(prev_ts) && act_timestamp != prev_ts
7929            && (((act_timestamp > prev_ts )? act_timestamp - prev_ts: prev_ts-act_timestamp)>2000)) {
7930        new_frame_interval = (act_timestamp > prev_ts)?
7931            act_timestamp - prev_ts :
7932            prev_ts - act_timestamp;
7933
7934        if (new_frame_interval < frm_int || frm_int == 0) {
7935            frm_int = new_frame_interval;
7936
7937            if (frm_int) {
7938                drv_ctx.frame_rate.fps_numerator = 1e6;
7939                drv_ctx.frame_rate.fps_denominator = frm_int;
7940                DEBUG_PRINT_LOW("set_frame_rate: frm_int(%u) fps(%f)",
7941                        frm_int, drv_ctx.frame_rate.fps_numerator /
7942                        (float)drv_ctx.frame_rate.fps_denominator);
7943                ioctl_msg.in = &drv_ctx.frame_rate;
7944
7945                if (ioctl (drv_ctx.video_driver_fd, VDEC_IOCTL_SET_FRAME_RATE,
7946                            (void*)&ioctl_msg) < 0) {
7947                    DEBUG_PRINT_ERROR("Setting frame rate failed");
7948                }
7949            }
7950        }
7951    }
7952
7953    prev_ts = act_timestamp;
7954}
7955
7956void omx_vdec::adjust_timestamp(OMX_S64 &act_timestamp)
7957{
7958    if (rst_prev_ts && VALID_TS(act_timestamp)) {
7959        prev_ts = act_timestamp;
7960        rst_prev_ts = false;
7961    } else if (VALID_TS(prev_ts)) {
7962        bool codec_cond = (drv_ctx.timestamp_adjust)?
7963            (!VALID_TS(act_timestamp) || (((act_timestamp > prev_ts)?
7964                                           (act_timestamp - prev_ts):(prev_ts - act_timestamp)) <= 2000)):
7965            (!VALID_TS(act_timestamp) || act_timestamp == prev_ts);
7966
7967        if (frm_int > 0 && codec_cond) {
7968            DEBUG_PRINT_LOW("adjust_timestamp: original ts[%lld]", act_timestamp);
7969            act_timestamp = prev_ts + frm_int;
7970            DEBUG_PRINT_LOW("adjust_timestamp: predicted ts[%lld]", act_timestamp);
7971            prev_ts = act_timestamp;
7972        } else
7973            set_frame_rate(act_timestamp);
7974    } else if (frm_int > 0)          // In this case the frame rate was set along
7975    {                               // with the port definition, start ts with 0
7976        act_timestamp = prev_ts = 0;  // and correct if a valid ts is received.
7977        rst_prev_ts = true;
7978    }
7979}
7980
7981void omx_vdec::handle_extradata_secure(OMX_BUFFERHEADERTYPE *p_buf_hdr)
7982{
7983    OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32];
7984    struct vdec_output_frameinfo *output_respbuf;
7985    OMX_U32 num_conceal_MB = 0;
7986    OMX_S64 ts_in_sei = 0;
7987    OMX_U32 frame_rate = 0;
7988    OMX_U32 extn_user_data_cnt = 0;
7989
7990    OMX_U32 index = p_buf_hdr - m_out_mem_ptr;
7991    OMX_U8 *meta_buffer_virtual = (OMX_U8 *)meta_buff.buffer;
7992
7993
7994    p_extra = (OMX_OTHER_EXTRADATATYPE *)
7995        ((unsigned)(meta_buffer_virtual +
7996            index * drv_ctx.op_buf.meta_buffer_size + 3)&(~3));
7997
7998    //mapping of ouput buffer to the corresponding meta buffer
7999    output_respbuf = (struct vdec_output_frameinfo *)\
8000                     p_buf_hdr->pOutputPortPrivate;
8001    output_respbuf->metadata_info.metabufaddr = (OMX_U8 *)p_extra;
8002    output_respbuf->metadata_info.size =
8003        drv_ctx.op_buf.meta_buffer_size;
8004
8005    meta_buffer_virtual = (OMX_U8 *)p_extra;
8006
8007    if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) {
8008        // Process driver extradata
8009        while (p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) {
8010            DEBUG_PRINT_LOW("handle_extradata_secure : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)",
8011                    p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize);
8012
8013            if (p_extra->nSize < p_extra->nDataSize) {
8014                DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d",
8015                        p_extra->nSize, p_extra->nDataSize);
8016                p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8017
8018                if ((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) ||
8019                        p_extra->nDataSize == 0 || p_extra->nSize == 0)
8020                    p_extra = NULL;
8021
8022                continue;
8023            }
8024
8025            if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) {
8026                if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8027                    num_conceal_MB = count_MB_in_extradata(p_extra);
8028
8029                if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)
8030                    // Map driver extradata to corresponding OMX type
8031                    p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB;
8032                else
8033                    p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8034
8035#ifdef _ANDROID_
8036
8037                if (m_debug_concealedmb) {
8038                    DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB);
8039                }
8040
8041#endif /* _ANDROID_ */
8042            } else if (p_extra->eType == VDEC_EXTRADATA_SEI) {
8043                p_sei = p_extra;
8044#ifdef MAX_RES_1080P
8045                h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8046#endif
8047                p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8048            } else if (p_extra->eType == VDEC_EXTRADATA_VUI) {
8049                p_vui = p_extra;
8050#ifdef MAX_RES_1080P
8051                h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8052#endif
8053                p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8054            } else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) {
8055                OMX_U8 *data_ptr = (OMX_U8*)p_extra->data;
8056                OMX_U32 value = 0;
8057                p_extn_user[extn_user_data_cnt] = p_extra;
8058                extn_user_data_cnt++;
8059
8060                if ((*data_ptr & 0xf0) == 0x20) {
8061                    value = ((*data_ptr) & 0x01);
8062                    data_ptr++;
8063
8064                    if (value)
8065                        data_ptr += 3;
8066
8067                    value = *((OMX_U32*)data_ptr);
8068                    value = ((value << 24) | (((value >> 8)<<24)>>8) |
8069                            (((value >> 16)<<24)>>16) | (value >> 24));
8070                    m_disp_hor_size = (value & 0xfffc0000)>>18;
8071                    m_disp_vert_size = (value & 0x0001fff8)>>3;
8072                    DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d",
8073                            m_disp_vert_size, m_disp_hor_size);
8074                }
8075            } else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) {
8076                p_extn_user[extn_user_data_cnt] = p_extra;
8077                extn_user_data_cnt++;
8078            }
8079
8080            print_debug_extradata(p_extra);
8081            p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8082
8083            if ((OMX_U8*)p_extra > (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size) ||
8084                    p_extra->nDataSize == 0 || p_extra->nSize == 0)
8085                p_extra = NULL;
8086        }
8087
8088        if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) {
8089            //moving p_extra to the starting location of the metadata buffer
8090            p_extra = (OMX_OTHER_EXTRADATATYPE *)meta_buffer_virtual;
8091            // Driver extradata is only exposed if MB map is requested by client,
8092            // otherwise can be overwritten by omx extradata.
8093            p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8094        }
8095    }
8096
8097    if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
8098        if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
8099            if (p_vui)
8100                h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8101
8102            if (p_sei)
8103                h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8104
8105            ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp);
8106
8107            if (!VALID_TS(p_buf_hdr->nTimeStamp))
8108                p_buf_hdr->nTimeStamp = ts_in_sei;
8109        } else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei)
8110            // If timeinfo is present frame info from SEI is already processed
8111            h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8112    }
8113
8114    if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) {
8115        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8116
8117        for (int i = 0; i < extn_user_data_cnt; i++) {
8118            if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) <
8119                    (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) {
8120                if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) {
8121                    append_extn_extradata(p_extra, p_extn_user[i]);
8122                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8123                } else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) {
8124                    append_user_extradata(p_extra, p_extn_user[i]);
8125                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8126                }
8127            }
8128        }
8129    }
8130
8131    if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra &&
8132            ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) <
8133            (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) {
8134        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8135        append_interlace_extradata(p_extra,
8136                ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index);
8137        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8138    }
8139
8140    if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra &&
8141            ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8142            (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) {
8143        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8144
8145        /* vui extra data (frame_rate) information */
8146        if (h264_parser)
8147            h264_parser->get_frame_rate(&frame_rate);
8148
8149        append_frame_info_extradata(p_extra, num_conceal_MB,
8150                ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type,
8151                p_buf_hdr->nTimeStamp, frame_rate,
8152                &((struct vdec_output_frameinfo *)
8153                    p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
8154        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8155    }
8156
8157    if ((client_extradata & OMX_PORTDEF_EXTRADATA) &&
8158            p_extra != NULL &&
8159            ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) <
8160            (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size)) {
8161        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8162        append_portdef_extradata(p_extra);
8163        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8164    }
8165
8166    if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)
8167        if (p_extra &&
8168                ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8169                (meta_buffer_virtual + drv_ctx.op_buf.meta_buffer_size))
8170            append_terminator_extradata(p_extra);
8171        else {
8172            DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added");
8173            p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8174        }
8175}
8176
8177void omx_vdec::handle_extradata(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8178{
8179    OMX_OTHER_EXTRADATATYPE *p_extra = NULL, *p_sei = NULL, *p_vui = NULL, *p_extn_user[32];
8180    OMX_U32 num_conceal_MB = 0;
8181    OMX_S64 ts_in_sei = 0;
8182    OMX_U32 frame_rate = 0;
8183    OMX_U32 extn_user_data_cnt = 0;
8184
8185    OMX_U32 index = p_buf_hdr - m_out_mem_ptr;
8186    OMX_U8* pBuffer = (OMX_U8 *)drv_ctx.ptr_outputbuffer[index].bufferaddr;
8187    p_extra = (OMX_OTHER_EXTRADATATYPE *)
8188        ((unsigned)(pBuffer + p_buf_hdr->nOffset +
8189            p_buf_hdr->nFilledLen + 3)&(~3));
8190
8191    if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen))
8192        p_extra = NULL;
8193
8194    if (drv_ctx.extradata && (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)) {
8195        // Process driver extradata
8196        while (p_extra && p_extra->eType != VDEC_EXTRADATA_NONE) {
8197            DEBUG_PRINT_LOW("handle_extradata : pBuf(%p) BufTS(%lld) Type(%x) DataSz(%u)",
8198                    p_buf_hdr, p_buf_hdr->nTimeStamp, p_extra->eType, p_extra->nDataSize);
8199
8200            if (p_extra->nSize < p_extra->nDataSize) {
8201                DEBUG_PRINT_ERROR(" \n Corrupt metadata Buffer size %d payload size %d",
8202                        p_extra->nSize, p_extra->nDataSize);
8203                p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8204
8205                if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) ||
8206                        p_extra->nDataSize == 0 || p_extra->nSize == 0)
8207                    p_extra = NULL;
8208
8209                continue;
8210            }
8211
8212            if (p_extra->eType == VDEC_EXTRADATA_MB_ERROR_MAP) {
8213                if (client_extradata & OMX_FRAMEINFO_EXTRADATA)
8214                    num_conceal_MB = count_MB_in_extradata(p_extra);
8215
8216                if (client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)
8217                    // Map driver extradata to corresponding OMX type
8218                    p_extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataConcealMB;
8219                else
8220                    p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8221
8222#ifdef _ANDROID_
8223
8224                if (m_debug_concealedmb) {
8225                    DEBUG_PRINT_HIGH("Concealed MB percentage is %u", num_conceal_MB);
8226                }
8227
8228#endif /* _ANDROID_ */
8229            } else if (p_extra->eType == VDEC_EXTRADATA_SEI) {
8230                p_sei = p_extra;
8231#ifdef MAX_RES_1080P
8232                h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8233#endif
8234                p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8235            } else if (p_extra->eType == VDEC_EXTRADATA_VUI) {
8236                p_vui = p_extra;
8237#ifdef MAX_RES_1080P
8238                h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8239#endif
8240                p_extra->eType = OMX_ExtraDataMax; // Invalid type to avoid expose this extradata to OMX client
8241            } else if (p_extra->eType == VDEC_EXTRADATA_EXT_DATA) {
8242                OMX_U8 *data_ptr = (OMX_U8*)p_extra->data;
8243                OMX_U32 value = 0;
8244                p_extn_user[extn_user_data_cnt] = p_extra;
8245                extn_user_data_cnt++;
8246
8247                if ((*data_ptr & 0xf0) == 0x20) {
8248                    value = ((*data_ptr) & 0x01);
8249                    data_ptr++;
8250
8251                    if (value)
8252                        data_ptr += 3;
8253
8254                    value = *((OMX_U32*)data_ptr);
8255                    value = ((value << 24) | (((value >> 8)<<24)>>8) |
8256                            (((value >> 16)<<24)>>16) | (value >> 24));
8257                    m_disp_hor_size = (value & 0xfffc0000)>>18;
8258                    m_disp_vert_size = (value & 0x0001fff8)>>3;
8259                    DEBUG_PRINT_LOW("Display Vertical Size = %d Display Horizontal Size = %d",
8260                            m_disp_vert_size, m_disp_hor_size);
8261                }
8262            } else if (p_extra->eType == VDEC_EXTRADATA_USER_DATA) {
8263                p_extn_user[extn_user_data_cnt] = p_extra;
8264                extn_user_data_cnt++;
8265            }
8266
8267            print_debug_extradata(p_extra);
8268            p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8269
8270            if ((OMX_U8*)p_extra > (pBuffer + p_buf_hdr->nAllocLen) ||
8271                    p_extra->nDataSize == 0 || p_extra->nSize == 0)
8272                p_extra = NULL;
8273        }
8274
8275        if (!(client_extradata & VDEC_EXTRADATA_MB_ERROR_MAP)) {
8276            // Driver extradata is only exposed if MB map is requested by client,
8277            // otherwise can be overwritten by omx extradata.
8278            p_extra = (OMX_OTHER_EXTRADATATYPE *)
8279                ((unsigned)(pBuffer + p_buf_hdr->nOffset +
8280                    p_buf_hdr->nFilledLen + 3)&(~3));
8281            p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8282        }
8283    }
8284
8285#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT
8286
8287    if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
8288        if (client_extradata & OMX_TIMEINFO_EXTRADATA) {
8289            if (p_vui)
8290                h264_parser->parse_nal((OMX_U8*)p_vui->data, p_vui->nDataSize, NALU_TYPE_VUI, false);
8291
8292            if (p_sei)
8293                h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8294
8295            ts_in_sei = h264_parser->process_ts_with_sei_vui(p_buf_hdr->nTimeStamp);
8296
8297            if (!VALID_TS(p_buf_hdr->nTimeStamp))
8298                p_buf_hdr->nTimeStamp = ts_in_sei;
8299        } else if ((client_extradata & OMX_FRAMEINFO_EXTRADATA) && p_sei)
8300            // If timeinfo is present frame info from SEI is already processed
8301            h264_parser->parse_nal((OMX_U8*)p_sei->data, p_sei->nDataSize, NALU_TYPE_SEI);
8302    }
8303
8304#endif
8305
8306    if (client_extradata & OMX_EXTNUSER_EXTRADATA && p_extra) {
8307        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8308
8309        for (int i = 0; i < extn_user_data_cnt; i++) {
8310            if (((OMX_U8*)p_extra + p_extn_user[i]->nSize) <
8311                    (pBuffer + p_buf_hdr->nAllocLen)) {
8312                if (p_extn_user[i]->eType == VDEC_EXTRADATA_EXT_DATA) {
8313                    append_extn_extradata(p_extra, p_extn_user[i]);
8314                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8315                } else if (p_extn_user[i]->eType == VDEC_EXTRADATA_USER_DATA) {
8316                    append_user_extradata(p_extra, p_extn_user[i]);
8317                    p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8318                }
8319            }
8320        }
8321    }
8322
8323    if ((client_extradata & OMX_INTERLACE_EXTRADATA) && p_extra &&
8324            ((OMX_U8*)p_extra + OMX_INTERLACE_EXTRADATA_SIZE) <
8325            (pBuffer + p_buf_hdr->nAllocLen)) {
8326        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8327        append_interlace_extradata(p_extra,
8328                ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->interlaced_format, index);
8329        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8330    }
8331
8332    if (client_extradata & OMX_FRAMEINFO_EXTRADATA && p_extra &&
8333            ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8334            (pBuffer + p_buf_hdr->nAllocLen)) {
8335        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8336
8337        /* vui extra data (frame_rate) information */
8338        if (h264_parser)
8339            h264_parser->get_frame_rate(&frame_rate);
8340
8341        append_frame_info_extradata(p_extra, num_conceal_MB,
8342                ((struct vdec_output_frameinfo *)p_buf_hdr->pOutputPortPrivate)->pic_type,
8343                p_buf_hdr->nTimeStamp, frame_rate,
8344                &((struct vdec_output_frameinfo *)
8345                    p_buf_hdr->pOutputPortPrivate)->aspect_ratio_info);
8346        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8347    }
8348
8349    if ((client_extradata & OMX_PORTDEF_EXTRADATA) &&
8350            p_extra != NULL &&
8351            ((OMX_U8*)p_extra + OMX_PORTDEF_EXTRADATA_SIZE) <
8352            (pBuffer + p_buf_hdr->nAllocLen)) {
8353        p_buf_hdr->nFlags |= OMX_BUFFERFLAG_EXTRADATA;
8354        append_portdef_extradata(p_extra);
8355        p_extra = (OMX_OTHER_EXTRADATATYPE *) (((OMX_U8 *) p_extra) + p_extra->nSize);
8356    }
8357
8358    if (p_buf_hdr->nFlags & OMX_BUFFERFLAG_EXTRADATA)
8359        if (p_extra &&
8360                ((OMX_U8*)p_extra + OMX_FRAMEINFO_EXTRADATA_SIZE) <
8361                (pBuffer + p_buf_hdr->nAllocLen))
8362            append_terminator_extradata(p_extra);
8363        else {
8364            DEBUG_PRINT_ERROR("ERROR: Terminator extradata cannot be added");
8365            p_buf_hdr->nFlags &= ~OMX_BUFFERFLAG_EXTRADATA;
8366        }
8367}
8368
8369OMX_ERRORTYPE omx_vdec::enable_extradata(OMX_U32 requested_extradata, bool enable)
8370{
8371    OMX_ERRORTYPE ret = OMX_ErrorNone;
8372    OMX_U32 driver_extradata = 0, extradata_size = 0;
8373    struct vdec_ioctl_msg ioctl_msg = {NULL, NULL};
8374
8375    if (m_state != OMX_StateLoaded) {
8376        DEBUG_PRINT_ERROR("ERROR: enable extradata allowed in Loaded state only");
8377        return OMX_ErrorIncorrectStateOperation;
8378    }
8379
8380    if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8381        extradata_size += OMX_FRAMEINFO_EXTRADATA_SIZE;
8382
8383    if (requested_extradata & OMX_INTERLACE_EXTRADATA)
8384        extradata_size += OMX_INTERLACE_EXTRADATA_SIZE;
8385
8386    if (requested_extradata & OMX_PORTDEF_EXTRADATA) {
8387        extradata_size += OMX_PORTDEF_EXTRADATA_SIZE;
8388    }
8389
8390    DEBUG_PRINT_ERROR("enable_extradata: actual[%x] requested[%x] enable[%d]",
8391            client_extradata, requested_extradata, enable);
8392
8393    if (enable)
8394        requested_extradata |= client_extradata;
8395    else {
8396        requested_extradata = client_extradata & ~requested_extradata;
8397        extradata_size *= -1;
8398    }
8399
8400    driver_extradata = requested_extradata & DRIVER_EXTRADATA_MASK;
8401
8402    if (secure_mode)
8403        driver_extradata = driver_extradata | VDEC_EXTRADATA_EXT_BUFFER;
8404
8405    if (requested_extradata & OMX_FRAMEINFO_EXTRADATA)
8406        driver_extradata |= VDEC_EXTRADATA_MB_ERROR_MAP; // Required for conceal MB frame info
8407
8408    if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) {
8409        driver_extradata |= ((requested_extradata & OMX_EXTNUSER_EXTRADATA)?
8410                VDEC_EXTRADATA_EXT_DATA | VDEC_EXTRADATA_USER_DATA : 0);
8411    }
8412
8413#ifdef PROCESS_EXTRADATA_IN_OUTPUT_PORT
8414
8415    if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
8416        driver_extradata |= ((requested_extradata & OMX_FRAMEINFO_EXTRADATA)?
8417                VDEC_EXTRADATA_SEI : 0); // Required for pan scan frame info
8418        driver_extradata |= ((requested_extradata & OMX_TIMEINFO_EXTRADATA)?
8419                VDEC_EXTRADATA_VUI | VDEC_EXTRADATA_SEI : 0); //Required for time info
8420    }
8421
8422#endif
8423
8424    if (driver_extradata != drv_ctx.extradata) {
8425        client_extradata = requested_extradata;
8426        drv_ctx.extradata = driver_extradata;
8427        ioctl_msg.in = &drv_ctx.extradata;
8428        ioctl_msg.out = NULL;
8429
8430        if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_SET_EXTRADATA,
8431                    (void*)&ioctl_msg) < 0) {
8432            DEBUG_PRINT_ERROR("\nSet extradata failed");
8433            ret = OMX_ErrorUnsupportedSetting;
8434        } else
8435            ret = get_buffer_req(&drv_ctx.op_buf);
8436    } else if ((client_extradata & ~DRIVER_EXTRADATA_MASK) != (requested_extradata & ~DRIVER_EXTRADATA_MASK)) {
8437        client_extradata = requested_extradata;
8438        drv_ctx.op_buf.buffer_size += extradata_size;
8439        // align the buffer size
8440        drv_ctx.op_buf.buffer_size = (drv_ctx.op_buf.buffer_size + drv_ctx.op_buf.alignment - 1)&(~(drv_ctx.op_buf.alignment - 1));
8441        DEBUG_PRINT_LOW("Aligned buffer size with exreadata = %d", drv_ctx.op_buf.buffer_size);
8442
8443        if (!(client_extradata & ~DRIVER_EXTRADATA_MASK)) // If no omx extradata is required remove space for terminator
8444            drv_ctx.op_buf.buffer_size -= sizeof(OMX_OTHER_EXTRADATATYPE);
8445
8446        ret = set_buffer_req(&drv_ctx.op_buf);
8447    }
8448
8449    return ret;
8450}
8451
8452OMX_U32 omx_vdec::count_MB_in_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8453{
8454    OMX_U32 num_MB = 0, byte_count = 0, num_MB_in_frame = 0;
8455    OMX_U8 *data_ptr = extra->data, data = 0;
8456
8457    while (byte_count < extra->nDataSize) {
8458        data = *data_ptr;
8459
8460        while (data) {
8461            num_MB += (data&0x01);
8462            data >>= 1;
8463        }
8464
8465        data_ptr++;
8466        byte_count++;
8467    }
8468
8469    num_MB_in_frame = ((drv_ctx.video_resolution.frame_width + 15) *
8470            (drv_ctx.video_resolution.frame_height + 15)) >> 8;
8471    return ((num_MB_in_frame > 0)?(num_MB * 100 / num_MB_in_frame) : 0);
8472}
8473
8474void omx_vdec::print_debug_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8475{
8476#ifdef _ANDROID_
8477
8478    if (!m_debug_extradata)
8479        return;
8480
8481    DEBUG_PRINT_HIGH(
8482            "============== Extra Data ==============\n"
8483            "           Size: %u \n"
8484            "        Version: %u \n"
8485            "      PortIndex: %u \n"
8486            "           Type: %x \n"
8487            "       DataSize: %u \n",
8488            extra->nSize, extra->nVersion.nVersion,
8489            extra->nPortIndex, extra->eType, extra->nDataSize);
8490
8491    if (extra->eType == OMX_ExtraDataInterlaceFormat) {
8492        OMX_STREAMINTERLACEFORMAT *intfmt = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8493        DEBUG_PRINT_HIGH(
8494                "------ Interlace Format ------\n"
8495                "                Size: %u \n"
8496                "             Version: %u \n"
8497                "           PortIndex: %u \n"
8498                " Is Interlace Format: %u \n"
8499                "   Interlace Formats: %u \n"
8500                "=========== End of Interlace ===========\n",
8501                intfmt->nSize, intfmt->nVersion.nVersion, intfmt->nPortIndex,
8502                intfmt->bInterlaceFormat, intfmt->nInterlaceFormats);
8503    } else if (extra->eType == OMX_ExtraDataFrameInfo) {
8504        OMX_QCOM_EXTRADATA_FRAMEINFO *fminfo = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8505
8506        DEBUG_PRINT_HIGH(
8507                "-------- Frame Format --------\n"
8508                "             Picture Type: %u \n"
8509                "           Interlace Type: %u \n"
8510                " Pan Scan Total Frame Num: %u \n"
8511                "   Concealed Macro Blocks: %u \n"
8512                "               frame rate: %u \n"
8513                "           Aspect Ratio X: %u \n"
8514                "           Aspect Ratio Y: %u \n",
8515                fminfo->ePicType,
8516                fminfo->interlaceType,
8517                fminfo->panScan.numWindows,
8518                fminfo->nConcealedMacroblocks,
8519                fminfo->nFrameRate,
8520                fminfo->aspectRatio.aspectRatioX,
8521                fminfo->aspectRatio.aspectRatioY);
8522
8523        for (int i = 0; i < fminfo->panScan.numWindows; i++) {
8524            DEBUG_PRINT_HIGH(
8525                    "------------------------------\n"
8526                    "     Pan Scan Frame Num: %d \n"
8527                    "            Rectangle x: %d \n"
8528                    "            Rectangle y: %d \n"
8529                    "           Rectangle dx: %d \n"
8530                    "           Rectangle dy: %d \n",
8531                    i, fminfo->panScan.window[i].x, fminfo->panScan.window[i].y,
8532                    fminfo->panScan.window[i].dx, fminfo->panScan.window[i].dy);
8533        }
8534
8535        DEBUG_PRINT_HIGH("========= End of Frame Format ==========");
8536    } else if (extra->eType == OMX_ExtraDataNone) {
8537        DEBUG_PRINT_HIGH("========== End of Terminator ===========");
8538    } else {
8539        DEBUG_PRINT_HIGH("======= End of Driver Extradata ========");
8540    }
8541
8542#endif /* _ANDROID_ */
8543}
8544
8545void omx_vdec::append_interlace_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8546        OMX_U32 interlaced_format_type, OMX_U32 buf_index)
8547{
8548    OMX_STREAMINTERLACEFORMAT *interlace_format;
8549    OMX_U32 mbaff = 0;
8550#if defined(_ANDROID_ICS_)
8551    OMX_U32 enable = 0;
8552    private_handle_t *handle = NULL;
8553    handle = (private_handle_t *)native_buffer[buf_index].nativehandle;
8554
8555    if (!handle)
8556        DEBUG_PRINT_LOW("%s: Native Buffer handle is NULL",__func__);
8557
8558#endif
8559    extra->nSize = OMX_INTERLACE_EXTRADATA_SIZE;
8560    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8561    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8562    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataInterlaceFormat;
8563    extra->nDataSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8564    interlace_format = (OMX_STREAMINTERLACEFORMAT *)extra->data;
8565    interlace_format->nSize = sizeof(OMX_STREAMINTERLACEFORMAT);
8566    interlace_format->nVersion.nVersion = OMX_SPEC_VERSION;
8567    interlace_format->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8568    mbaff = (h264_parser)? (h264_parser->is_mbaff()): false;
8569
8570    if ((interlaced_format_type == VDEC_InterlaceFrameProgressive)  && !mbaff) {
8571        interlace_format->bInterlaceFormat = OMX_FALSE;
8572        interlace_format->nInterlaceFormats = OMX_InterlaceFrameProgressive;
8573        drv_ctx.interlace = VDEC_InterlaceFrameProgressive;
8574#if defined(_ANDROID_ICS_)
8575
8576        if (handle) {
8577            setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable);
8578        }
8579
8580#endif
8581    } else {
8582        interlace_format->bInterlaceFormat = OMX_TRUE;
8583        interlace_format->nInterlaceFormats = OMX_InterlaceInterleaveFrameTopFieldFirst;
8584        drv_ctx.interlace = VDEC_InterlaceInterleaveFrameTopFieldFirst;
8585#if defined(_ANDROID_ICS_)
8586        enable = 1;
8587
8588        if (handle) {
8589            setMetaData(handle, PP_PARAM_INTERLACED, (void*)&enable);
8590        }
8591
8592#endif
8593    }
8594
8595    print_debug_extradata(extra);
8596}
8597
8598void omx_vdec::append_frame_info_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8599        OMX_U32 num_conceal_mb, OMX_U32 picture_type, OMX_S64 timestamp,
8600        OMX_U32 frame_rate, struct vdec_aspectratioinfo *aspect_ratio_info)
8601{
8602    OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info = NULL;
8603    extra->nSize = OMX_FRAMEINFO_EXTRADATA_SIZE;
8604    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8605    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8606    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataFrameInfo;
8607    extra->nDataSize = sizeof(OMX_QCOM_EXTRADATA_FRAMEINFO);
8608    frame_info = (OMX_QCOM_EXTRADATA_FRAMEINFO *)extra->data;
8609
8610    switch (picture_type) {
8611        case PICTURE_TYPE_I:
8612            frame_info->ePicType = OMX_VIDEO_PictureTypeI;
8613            break;
8614        case PICTURE_TYPE_P:
8615            frame_info->ePicType = OMX_VIDEO_PictureTypeP;
8616            break;
8617        case PICTURE_TYPE_B:
8618            frame_info->ePicType = OMX_VIDEO_PictureTypeB;
8619            break;
8620        default:
8621            frame_info->ePicType = (OMX_VIDEO_PICTURETYPE)0;
8622    }
8623
8624    if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameTopFieldFirst)
8625        frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameTopFieldFirst;
8626    else if (drv_ctx.interlace == VDEC_InterlaceInterleaveFrameBottomFieldFirst)
8627        frame_info->interlaceType = OMX_QCOM_InterlaceInterleaveFrameBottomFieldFirst;
8628    else
8629        frame_info->interlaceType = OMX_QCOM_InterlaceFrameProgressive;
8630
8631    memset(&frame_info->panScan,0,sizeof(frame_info->panScan));
8632    memset(&frame_info->aspectRatio, 0, sizeof(frame_info->aspectRatio));
8633    memset(&frame_info->displayAspectRatio, 0, sizeof(frame_info->displayAspectRatio));
8634
8635    if (drv_ctx.decoder_format == VDEC_CODECTYPE_H264) {
8636        h264_parser->fill_pan_scan_data(&frame_info->panScan, timestamp);
8637    }
8638
8639    fill_aspect_ratio_info(aspect_ratio_info, frame_info);
8640
8641    if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) {
8642        if (m_disp_hor_size && m_disp_vert_size) {
8643            frame_info->displayAspectRatio.displayHorizontalSize = m_disp_hor_size;
8644            frame_info->displayAspectRatio.displayVerticalSize = m_disp_vert_size;
8645        }
8646    }
8647
8648    frame_info->nConcealedMacroblocks = num_conceal_mb;
8649    frame_info->nFrameRate = frame_rate;
8650    print_debug_extradata(extra);
8651}
8652
8653void omx_vdec::fill_aspect_ratio_info(
8654        struct vdec_aspectratioinfo *aspect_ratio_info,
8655        OMX_QCOM_EXTRADATA_FRAMEINFO *frame_info)
8656{
8657    m_extradata = frame_info;
8658
8659    if (drv_ctx.decoder_format == VDEC_CODECTYPE_MPEG2) {
8660        switch (aspect_ratio_info->aspect_ratio) {
8661            case 1:
8662                m_extradata->aspectRatio.aspectRatioX = 1;
8663                m_extradata->aspectRatio.aspectRatioY = 1;
8664                break;
8665            case 2:
8666
8667                if (m_disp_hor_size && m_disp_vert_size) {
8668                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8669                        m_disp_vert_size;
8670                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8671                        m_disp_hor_size;
8672                } else {
8673                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8674                        drv_ctx.video_resolution.frame_height;
8675                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8676                        drv_ctx.video_resolution.frame_width;
8677                }
8678
8679                break;
8680            case 3:
8681
8682                if (m_disp_hor_size && m_disp_vert_size) {
8683                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8684                        m_disp_vert_size;
8685                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8686                        m_disp_hor_size;
8687                } else {
8688                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8689                        drv_ctx.video_resolution.frame_height;
8690                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8691                        drv_ctx.video_resolution.frame_width;
8692                }
8693
8694                break;
8695            case 4:
8696
8697                if (m_disp_hor_size && m_disp_vert_size) {
8698                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8699                        m_disp_vert_size;
8700                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8701                        m_disp_hor_size;
8702                } else {
8703                    m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width *
8704                        drv_ctx.video_resolution.frame_height;
8705                    m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height *
8706                        drv_ctx.video_resolution.frame_width;
8707                }
8708
8709                break;
8710            default:
8711                m_extradata->aspectRatio.aspectRatioX = 1;
8712                m_extradata->aspectRatio.aspectRatioY = 1;
8713        }
8714    } else {
8715        m_extradata->aspectRatio.aspectRatioX = aspect_ratio_info->par_width;
8716        m_extradata->aspectRatio.aspectRatioY = aspect_ratio_info->par_height;
8717    }
8718
8719    DEBUG_PRINT_LOW("aspectRatioX %d aspectRatioX %d", m_extradata->aspectRatio.aspectRatioX,
8720            m_extradata->aspectRatio.aspectRatioY);
8721}
8722
8723void omx_vdec::append_portdef_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8724{
8725    OMX_PARAM_PORTDEFINITIONTYPE *portDefn = NULL;
8726    extra->nSize = OMX_PORTDEF_EXTRADATA_SIZE;
8727    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8728    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8729    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataPortDef;
8730    extra->nDataSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
8731    portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *)extra->data;
8732    *portDefn = m_port_def;
8733    DEBUG_PRINT_LOW("append_portdef_extradata height = %u width = %u stride = %u"
8734            "sliceheight = %u",portDefn->format.video.nFrameHeight,
8735            portDefn->format.video.nFrameWidth,
8736            portDefn->format.video.nStride,
8737            portDefn->format.video.nSliceHeight);
8738}
8739
8740void omx_vdec::append_extn_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8741        OMX_OTHER_EXTRADATATYPE *p_extn)
8742{
8743    extra->nDataSize = p_extn->nDataSize;
8744    extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize);
8745    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8746    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8747    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2ExtnData;
8748
8749    if (extra->data && p_extn->data && extra->nDataSize)
8750        memcpy(extra->data, p_extn->data, extra->nDataSize);
8751}
8752
8753void omx_vdec::append_user_extradata(OMX_OTHER_EXTRADATATYPE *extra,
8754        OMX_OTHER_EXTRADATATYPE *p_user)
8755{
8756    extra->nDataSize = p_user->nDataSize;
8757    extra->nSize = (sizeof(OMX_OTHER_EXTRADATATYPE) + extra->nDataSize);
8758    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8759    extra->nPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
8760    extra->eType = (OMX_EXTRADATATYPE)OMX_ExtraDataMP2UserData;
8761
8762    if (extra->data && p_user->data && extra->nDataSize)
8763        memcpy(extra->data, p_user->data, extra->nDataSize);
8764}
8765
8766void omx_vdec::append_terminator_extradata(OMX_OTHER_EXTRADATATYPE *extra)
8767{
8768    extra->nSize = sizeof(OMX_OTHER_EXTRADATATYPE);
8769    extra->nVersion.nVersion = OMX_SPEC_VERSION;
8770    extra->eType = OMX_ExtraDataNone;
8771    extra->nDataSize = 0;
8772    extra->data[0] = 0;
8773
8774    print_debug_extradata(extra);
8775}
8776
8777OMX_ERRORTYPE  omx_vdec::allocate_desc_buffer(OMX_U32 index)
8778{
8779    OMX_ERRORTYPE eRet = OMX_ErrorNone;
8780
8781    if (index >= drv_ctx.ip_buf.actualcount) {
8782        DEBUG_PRINT_ERROR("\nERROR:Desc Buffer Index not found");
8783        return OMX_ErrorInsufficientResources;
8784    }
8785
8786    if (m_desc_buffer_ptr == NULL) {
8787        m_desc_buffer_ptr = (desc_buffer_hdr*) \
8788                            calloc( (sizeof(desc_buffer_hdr)),
8789                                    drv_ctx.ip_buf.actualcount);
8790
8791        if (m_desc_buffer_ptr == NULL) {
8792            DEBUG_PRINT_ERROR("\n m_desc_buffer_ptr Allocation failed ");
8793            return OMX_ErrorInsufficientResources;
8794        }
8795    }
8796
8797    m_desc_buffer_ptr[index].buf_addr = (unsigned char *)malloc (DESC_BUFFER_SIZE * sizeof(OMX_U8));
8798
8799    if (m_desc_buffer_ptr[index].buf_addr == NULL) {
8800        DEBUG_PRINT_ERROR("\ndesc buffer Allocation failed ");
8801        return OMX_ErrorInsufficientResources;
8802    }
8803
8804    return eRet;
8805}
8806
8807void omx_vdec::insert_demux_addr_offset(OMX_U32 address_offset)
8808{
8809    DEBUG_PRINT_LOW("Inserting address offset (%d) at idx (%d)", address_offset,m_demux_entries);
8810
8811    if (m_demux_entries < 8192) {
8812        m_demux_offsets[m_demux_entries++] = address_offset;
8813    }
8814
8815    return;
8816}
8817
8818void omx_vdec::extract_demux_addr_offsets(OMX_BUFFERHEADERTYPE *buf_hdr)
8819{
8820    OMX_U32 bytes_to_parse = buf_hdr->nFilledLen;
8821    OMX_U8 *buf = buf_hdr->pBuffer + buf_hdr->nOffset;
8822    OMX_U32 index = 0;
8823    OMX_U32 prev_sc_index = 0;
8824
8825    m_demux_entries = 0;
8826
8827    while (index < bytes_to_parse) {
8828        if ( ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8829                    (buf[index+2] == 0x00) && (buf[index+3] == 0x01)) ||
8830                ((buf[index] == 0x00) && (buf[index+1] == 0x00) &&
8831                 (buf[index+2] == 0x01)) ) {
8832            if ((((index+3) - prev_sc_index) <= 4) && m_demux_entries) {
8833                DEBUG_PRINT_ERROR("FOUND Consecutive start Code, Hence skip one");
8834                m_demux_entries--;
8835            }
8836
8837            //Found start code, insert address offset
8838            insert_demux_addr_offset(index);
8839
8840            if (buf[index+2] == 0x01) // 3 byte start code
8841                index += 3;
8842            else                      //4 byte start code
8843                index += 4;
8844
8845            prev_sc_index = index;
8846        } else
8847            index++;
8848    }
8849
8850    DEBUG_PRINT_LOW("Extracted (%d) demux entry offsets",m_demux_entries);
8851    return;
8852}
8853
8854OMX_ERRORTYPE omx_vdec::handle_demux_data(OMX_BUFFERHEADERTYPE *p_buf_hdr)
8855{
8856    //fix this, handle 3 byte start code, vc1 terminator entry
8857    OMX_U8 *p_demux_data = NULL;
8858    OMX_U32 desc_data = 0;
8859    OMX_U32 start_addr = 0;
8860    OMX_U32 nal_size = 0;
8861    OMX_U32 suffix_byte = 0;
8862    OMX_U32 demux_index = 0;
8863    OMX_U32 buffer_index = 0;
8864
8865    if (m_desc_buffer_ptr == NULL) {
8866        DEBUG_PRINT_ERROR("m_desc_buffer_ptr is NULL. Cannot append demux entries.");
8867        return OMX_ErrorBadParameter;
8868    }
8869
8870    buffer_index = p_buf_hdr - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
8871
8872    if (buffer_index > drv_ctx.ip_buf.actualcount) {
8873        DEBUG_PRINT_ERROR("handle_demux_data:Buffer index is incorrect (%d)", buffer_index);
8874        return OMX_ErrorBadParameter;
8875    }
8876
8877    p_demux_data = (OMX_U8 *) m_desc_buffer_ptr[buffer_index].buf_addr;
8878
8879    if ( ((OMX_U8*)p_demux_data == NULL) ||
8880            ((m_demux_entries * 16) + 1) > DESC_BUFFER_SIZE) {
8881        DEBUG_PRINT_ERROR("Insufficient buffer. Cannot append demux entries.");
8882        return OMX_ErrorBadParameter;
8883    } else {
8884        for (; demux_index < m_demux_entries; demux_index++) {
8885            desc_data = 0;
8886            start_addr = m_demux_offsets[demux_index];
8887
8888            if (p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 2] == 0x01) {
8889                suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 3];
8890            } else {
8891                suffix_byte = p_buf_hdr->pBuffer[m_demux_offsets[demux_index] + 4];
8892            }
8893
8894            if (demux_index < (m_demux_entries - 1)) {
8895                nal_size = m_demux_offsets[demux_index + 1] - m_demux_offsets[demux_index] - 2;
8896            } else {
8897                nal_size = p_buf_hdr->nFilledLen - m_demux_offsets[demux_index] - 2;
8898            }
8899
8900            DEBUG_PRINT_LOW("Start_addr(%p), suffix_byte(0x%x),nal_size(%d),demux_index(%d)",
8901                    start_addr,
8902                    suffix_byte,
8903                    nal_size,
8904                    demux_index);
8905            desc_data = (start_addr >> 3) << 1;
8906            desc_data |= (start_addr & 7) << 21;
8907            desc_data |= suffix_byte << 24;
8908
8909            memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8910            memcpy(p_demux_data + 4, &nal_size, sizeof(OMX_U32));
8911            memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8912            memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8913
8914            p_demux_data += 16;
8915        }
8916
8917        if (codec_type_parse == CODEC_TYPE_VC1) {
8918            DEBUG_PRINT_LOW("VC1 terminator entry");
8919            desc_data = 0;
8920            desc_data = 0x82 << 24;
8921            memcpy(p_demux_data, &desc_data, sizeof(OMX_U32));
8922            memset(p_demux_data + 4, 0, sizeof(OMX_U32));
8923            memset(p_demux_data + 8, 0, sizeof(OMX_U32));
8924            memset(p_demux_data + 12, 0, sizeof(OMX_U32));
8925            p_demux_data += 16;
8926            m_demux_entries++;
8927        }
8928
8929        //Add zero word to indicate end of descriptors
8930        memset(p_demux_data, 0, sizeof(OMX_U32));
8931
8932        m_desc_buffer_ptr[buffer_index].desc_data_size = (m_demux_entries * 16) + sizeof(OMX_U32);
8933        DEBUG_PRINT_LOW("desc table data size=%d", m_desc_buffer_ptr[buffer_index].desc_data_size);
8934    }
8935
8936    memset(m_demux_offsets, 0, ( sizeof(OMX_U32) * 8192) );
8937    m_demux_entries = 0;
8938    DEBUG_PRINT_LOW("Demux table complete!");
8939    return OMX_ErrorNone;
8940}
8941
8942#ifdef MAX_RES_1080P
8943
8944OMX_ERRORTYPE omx_vdec::vdec_alloc_meta_buffers()
8945{
8946    OMX_U32 pmem_fd = -1, pmem_fd_iommu = -1;
8947    OMX_U32 size, alignment;
8948    void *buf_addr = NULL;
8949    struct vdec_ioctl_msg ioctl_msg;
8950#ifndef USE_ION
8951    struct pmem_allocation allocation;
8952#endif
8953    struct vdec_meta_buffers meta_buffer;
8954
8955    memset ((unsigned char*)&meta_buffer,0,sizeof (struct vdec_meta_buffers));
8956
8957    //we already have meta buffer size.
8958    size = drv_ctx.op_buf.meta_buffer_size * drv_ctx.op_buf.actualcount;
8959    alignment = 8192;
8960
8961
8962#ifdef USE_ION
8963    external_meta_buffer = true;
8964    drv_ctx.meta_buffer.ion_device_fd = alloc_map_ion_memory(
8965            size, 8192,
8966            &drv_ctx.meta_buffer.ion_alloc_data,
8967            &drv_ctx.meta_buffer.fd_ion_data, 0);
8968
8969    if (drv_ctx.meta_buffer.ion_device_fd < 0) {
8970        external_meta_buffer = false;
8971        return OMX_ErrorInsufficientResources;
8972    }
8973
8974    external_meta_buffer = false;
8975    pmem_fd = drv_ctx.meta_buffer.fd_ion_data.fd;
8976
8977    external_meta_buffer_iommu = true;
8978    drv_ctx.meta_buffer_iommu.ion_device_fd = alloc_map_ion_memory(
8979            size, 8192,
8980            &drv_ctx.meta_buffer_iommu.ion_alloc_data,
8981            &drv_ctx.meta_buffer_iommu.fd_ion_data, 0);
8982
8983    if (drv_ctx.meta_buffer_iommu.ion_device_fd < 0) {
8984        external_meta_buffer_iommu = false;
8985        return OMX_ErrorInsufficientResources;
8986    }
8987
8988    external_meta_buffer_iommu = false;
8989    pmem_fd_iommu = drv_ctx.meta_buffer_iommu.fd_ion_data.fd;
8990#else
8991    allocation.size = size;
8992    allocation.align = clip2(alignment);
8993
8994    if (allocation.align != 8192)
8995        allocation.align = 8192;
8996
8997    pmem_fd = open(MEM_DEVICE, O_RDWR);
8998
8999    if ((int)(pmem_fd) < 0)
9000        return OMX_ErrorInsufficientResources;
9001
9002    if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
9003        DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
9004                allocation.align, allocation.size);
9005        return OMX_ErrorInsufficientResources;
9006    }
9007
9008#endif
9009
9010    buf_addr = mmap(NULL, size,
9011            PROT_READ | PROT_WRITE,
9012            MAP_SHARED, pmem_fd_iommu, 0);
9013
9014    if (buf_addr == (void*) MAP_FAILED) {
9015        close(pmem_fd);
9016        close(pmem_fd_iommu);
9017#ifdef USE_ION
9018        free_ion_memory(&drv_ctx.meta_buffer);
9019        free_ion_memory(&drv_ctx.meta_buffer_iommu);
9020#endif
9021        pmem_fd = -1;
9022        pmem_fd_iommu = -1;
9023        DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
9024        return OMX_ErrorInsufficientResources;
9025    }
9026
9027    meta_buffer.size = size;
9028    meta_buffer.count = drv_ctx.op_buf.actualcount;
9029    meta_buffer.pmem_fd = pmem_fd;
9030    meta_buffer.pmem_fd_iommu = pmem_fd_iommu;
9031    meta_buffer.offset = 0;
9032
9033    ioctl_msg.in = (void*)&meta_buffer;
9034    ioctl_msg.out = NULL;
9035
9036    if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_META_BUFFERS, (void*)&ioctl_msg) < 0) {
9037        DEBUG_PRINT_ERROR("Failed to set the meta_buffers\n");
9038        return OMX_ErrorInsufficientResources;
9039    }
9040
9041    meta_buff.buffer = (unsigned char *) buf_addr;
9042    meta_buff.size = size;
9043    meta_buff.count = drv_ctx.op_buf.actualcount;
9044    meta_buff.offset = 0;
9045    meta_buff.pmem_fd = pmem_fd;
9046    meta_buff.pmem_fd_iommu = pmem_fd_iommu;
9047    DEBUG_PRINT_HIGH("Saving virt:%p, FD: %d and FD_IOMMU %d of size %d count: %d", meta_buff.buffer,
9048            meta_buff.pmem_fd, meta_buff.pmem_fd_iommu, meta_buff.size, drv_ctx.op_buf.actualcount);
9049    return OMX_ErrorNone;
9050}
9051
9052void omx_vdec::vdec_dealloc_meta_buffers()
9053{
9054    if (meta_buff.pmem_fd > 0) {
9055        if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_META_BUFFERS,NULL) < 0)
9056            DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_META_BUFFERS failed");
9057
9058        close(meta_buff.pmem_fd);
9059#ifdef USE_ION
9060        free_ion_memory(&drv_ctx.meta_buffer);
9061#endif
9062    }
9063
9064    if (meta_buff.pmem_fd_iommu > 0) {
9065        munmap(meta_buff.buffer, meta_buff.size);
9066        close(meta_buff.pmem_fd_iommu);
9067#ifdef USE_ION
9068        free_ion_memory(&drv_ctx.meta_buffer_iommu);
9069#endif
9070        DEBUG_PRINT_LOW("Cleaning Meta buffer of size %d",meta_buff.size);
9071        meta_buff.pmem_fd = -1;
9072        meta_buff.pmem_fd_iommu = -1;
9073        meta_buff.offset = 0;
9074        meta_buff.size = 0;
9075        meta_buff.count = 0;
9076        meta_buff.buffer = NULL;
9077    }
9078}
9079
9080OMX_ERRORTYPE omx_vdec::vdec_alloc_h264_mv()
9081{
9082    OMX_U32 pmem_fd = -1;
9083    OMX_U32 width, height, size, alignment;
9084    void *buf_addr = NULL;
9085    struct vdec_ioctl_msg ioctl_msg;
9086#ifndef USE_ION
9087    struct pmem_allocation allocation;
9088#endif
9089    struct vdec_h264_mv h264_mv;
9090    struct vdec_mv_buff_size mv_buff_size;
9091
9092    mv_buff_size.width = drv_ctx.video_resolution.stride;
9093    mv_buff_size.height = drv_ctx.video_resolution.scan_lines>>2;
9094
9095    ioctl_msg.in = NULL;
9096    ioctl_msg.out = (void*)&mv_buff_size;
9097
9098    if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_GET_MV_BUFFER_SIZE, (void*)&ioctl_msg) < 0) {
9099        DEBUG_PRINT_ERROR("\n GET_MV_BUFFER_SIZE Failed for width: %d, Height %d" ,
9100                mv_buff_size.width, mv_buff_size.height);
9101        return OMX_ErrorInsufficientResources;
9102    }
9103
9104    DEBUG_PRINT_ERROR("GET_MV_BUFFER_SIZE returned: Size: %d and alignment: %d",
9105            mv_buff_size.size, mv_buff_size.alignment);
9106
9107    size = mv_buff_size.size * drv_ctx.op_buf.actualcount;
9108    alignment = mv_buff_size.alignment;
9109
9110    DEBUG_PRINT_LOW("Entered vdec_alloc_h264_mv act_width: %d, act_height: %d, size: %d, alignment %d",
9111            drv_ctx.video_resolution.frame_width, drv_ctx.video_resolution.frame_height,size,alignment);
9112
9113
9114#ifdef USE_ION
9115    drv_ctx.h264_mv.ion_device_fd = alloc_map_ion_memory(
9116            size, 8192,
9117            &drv_ctx.h264_mv.ion_alloc_data,
9118            &drv_ctx.h264_mv.fd_ion_data,ION_FLAG_CACHED);
9119
9120    if (drv_ctx.h264_mv.ion_device_fd < 0) {
9121        return OMX_ErrorInsufficientResources;
9122    }
9123
9124    pmem_fd = drv_ctx.h264_mv.fd_ion_data.fd;
9125#else
9126    allocation.size = size;
9127    allocation.align = clip2(alignment);
9128
9129    if (allocation.align != 8192)
9130        allocation.align = 8192;
9131
9132    pmem_fd = open(MEM_DEVICE, O_RDWR);
9133
9134    if ((int)(pmem_fd) < 0)
9135        return OMX_ErrorInsufficientResources;
9136
9137    if (ioctl(pmem_fd, PMEM_ALLOCATE_ALIGNED, &allocation) < 0) {
9138        DEBUG_PRINT_ERROR("\n Aligment(%u) failed with pmem driver Sz(%lu)",
9139                allocation.align, allocation.size);
9140        return OMX_ErrorInsufficientResources;
9141    }
9142
9143#endif
9144
9145    if (!secure_mode) {
9146        buf_addr = mmap(NULL, size,
9147                PROT_READ | PROT_WRITE,
9148                MAP_SHARED, pmem_fd, 0);
9149
9150        if (buf_addr == (void*) MAP_FAILED) {
9151            close(pmem_fd);
9152#ifdef USE_ION
9153            free_ion_memory(&drv_ctx.h264_mv);
9154#endif
9155            pmem_fd = -1;
9156            DEBUG_PRINT_ERROR("Error returned in allocating recon buffers buf_addr: %p\n",buf_addr);
9157            return OMX_ErrorInsufficientResources;
9158        }
9159    } else
9160        buf_addr =(unsigned char *) (pmem_fd + 1234);
9161
9162    DEBUG_PRINT_LOW("Allocated virt:%p, FD: %d of size %d count: %d", buf_addr,
9163            pmem_fd, size, drv_ctx.op_buf.actualcount);
9164
9165    h264_mv.size = size;
9166    h264_mv.count = drv_ctx.op_buf.actualcount;
9167    h264_mv.pmem_fd = pmem_fd;
9168    h264_mv.offset = 0;
9169
9170    ioctl_msg.in = (void*)&h264_mv;
9171    ioctl_msg.out = NULL;
9172
9173    if (ioctl (drv_ctx.video_driver_fd,VDEC_IOCTL_SET_H264_MV_BUFFER, (void*)&ioctl_msg) < 0) {
9174        DEBUG_PRINT_ERROR("Failed to set the H264_mv_buffers\n");
9175        return OMX_ErrorInsufficientResources;
9176    }
9177
9178    h264_mv_buff.buffer = (unsigned char *) buf_addr;
9179    h264_mv_buff.size = size;
9180    h264_mv_buff.count = drv_ctx.op_buf.actualcount;
9181    h264_mv_buff.offset = 0;
9182    h264_mv_buff.pmem_fd = pmem_fd;
9183    DEBUG_PRINT_LOW("Saving virt:%p, FD: %d of size %d count: %d", h264_mv_buff.buffer,
9184            h264_mv_buff.pmem_fd, h264_mv_buff.size, drv_ctx.op_buf.actualcount);
9185    return OMX_ErrorNone;
9186}
9187
9188void omx_vdec::vdec_dealloc_h264_mv()
9189{
9190    if (h264_mv_buff.pmem_fd > 0) {
9191        if (ioctl(drv_ctx.video_driver_fd, VDEC_IOCTL_FREE_H264_MV_BUFFER,NULL) < 0)
9192            DEBUG_PRINT_ERROR("VDEC_IOCTL_FREE_H264_MV_BUFFER failed");
9193
9194        if (!secure_mode)
9195            munmap(h264_mv_buff.buffer, h264_mv_buff.size);
9196
9197        close(h264_mv_buff.pmem_fd);
9198#ifdef USE_ION
9199        free_ion_memory(&drv_ctx.h264_mv);
9200#endif
9201        DEBUG_PRINT_LOW("Cleaning H264_MV buffer of size %d",h264_mv_buff.size);
9202        h264_mv_buff.pmem_fd = -1;
9203        h264_mv_buff.offset = 0;
9204        h264_mv_buff.size = 0;
9205        h264_mv_buff.count = 0;
9206        h264_mv_buff.buffer = NULL;
9207    }
9208}
9209
9210#endif
9211
9212#ifdef _ANDROID_
9213OMX_ERRORTYPE omx_vdec::createDivxDrmContext()
9214{
9215    OMX_ERRORTYPE err = OMX_ErrorNone;
9216    iDivXDrmDecrypt = DivXDrmDecrypt::Create();
9217
9218    if (iDivXDrmDecrypt) {
9219        OMX_ERRORTYPE err = iDivXDrmDecrypt->Init();
9220
9221        if (err!=OMX_ErrorNone) {
9222            DEBUG_PRINT_ERROR("\nERROR :iDivXDrmDecrypt->Init %d", err);
9223            delete iDivXDrmDecrypt;
9224            iDivXDrmDecrypt = NULL;
9225        }
9226    } else {
9227        DEBUG_PRINT_ERROR("\nUnable to Create DIVX DRM");
9228        err = OMX_ErrorUndefined;
9229    }
9230
9231    return err;
9232}
9233#endif //_ANDROID_
9234
9235OMX_ERRORTYPE omx_vdec::power_module_register()
9236{
9237    char powerHintMetadata[512];
9238
9239    if (m_power_hinted) {
9240        return OMX_ErrorBadParameter; //need a proper error code
9241    }
9242
9243    PowerModule * pm = PowerModule::getInstance();
9244
9245    if (pm == NULL) {
9246        DEBUG_PRINT_ERROR("failed to get power module instance");
9247        return OMX_ErrorBadParameter;
9248    }
9249
9250    power_module_t * ph = pm->getPowerModuleHandle();
9251
9252    if (ph == NULL) {
9253        DEBUG_PRINT_ERROR("failed to get power module handle");
9254        return OMX_ErrorBadParameter;
9255    }
9256
9257    if (ph->powerHint) {
9258        snprintf(powerHintMetadata, sizeof(powerHintMetadata) - 1,
9259                "state=1;framewidth=%u;frameheight=%u;bitrate=%u",
9260                m_port_def.format.video.nFrameWidth, m_port_def.format.video.nFrameHeight,
9261                m_port_def.format.video.nBitrate);
9262        powerHintMetadata[sizeof(powerHintMetadata) - 1] = '\0';
9263
9264        ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)powerHintMetadata);
9265        m_power_hinted = true;
9266    } else {
9267        DEBUG_PRINT_ERROR("No hint called for register");
9268    }
9269
9270    return OMX_ErrorNone;
9271}
9272
9273OMX_ERRORTYPE omx_vdec::power_module_deregister()
9274{
9275    if (!m_power_hinted) {
9276        return OMX_ErrorBadParameter; //need a proper error code
9277    }
9278
9279    PowerModule * pm = PowerModule::getInstance();
9280
9281    if (pm == NULL) {
9282        DEBUG_PRINT_ERROR("failed to get power module instance");
9283        return OMX_ErrorBadParameter;
9284    }
9285
9286    power_module_t * ph = pm->getPowerModuleHandle();
9287
9288    if (ph == NULL) {
9289        DEBUG_PRINT_ERROR("failed to get power module handle");
9290        return OMX_ErrorBadParameter;
9291    }
9292
9293    if (ph->powerHint) {
9294        ph->powerHint(ph, POWER_HINT_VIDEO_DECODE, (void *)"state=0");
9295        m_power_hinted = false;
9296    } else {
9297        DEBUG_PRINT_ERROR("No hint called for deregister");
9298    }
9299
9300    return OMX_ErrorNone;
9301}
9302omx_vdec::allocate_color_convert_buf::allocate_color_convert_buf()
9303{
9304    enabled = false;
9305    omx = NULL;
9306    init_members();
9307    ColorFormat = OMX_COLOR_FormatMax;
9308}
9309
9310void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
9311{
9312    omx = reinterpret_cast<omx_vdec*>(client);
9313}
9314
9315void omx_vdec::allocate_color_convert_buf::init_members()
9316{
9317    allocated_count = 0;
9318    buffer_size_req = 0;
9319    buffer_alignment_req = 0;
9320    memset(m_platform_list_client,0,sizeof(m_platform_list_client));
9321    memset(m_platform_entry_client,0,sizeof(m_platform_entry_client));
9322    memset(m_pmem_info_client,0,sizeof(m_pmem_info_client));
9323    memset(m_out_mem_ptr_client,0,sizeof(m_out_mem_ptr_client));
9324    memset(op_buf_ion_info,0,sizeof(m_platform_entry_client));
9325
9326    for (int i = 0; i < MAX_COUNT; i++)
9327        pmem_fd[i] = -1;
9328}
9329
9330omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
9331{
9332    c2d.destroy();
9333}
9334
9335bool omx_vdec::allocate_color_convert_buf::update_buffer_req()
9336{
9337    bool status = true;
9338    unsigned int src_size = 0, destination_size = 0;
9339    OMX_COLOR_FORMATTYPE drv_color_format;
9340
9341    if (!omx) {
9342        DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9343        return false;
9344    }
9345
9346    if (!enabled) {
9347        DEBUG_PRINT_ERROR("\n No color conversion required");
9348        return status;
9349    }
9350
9351    if (omx->drv_ctx.output_format != VDEC_YUV_FORMAT_TILE_4x2 &&
9352            ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9353        DEBUG_PRINT_ERROR("\nupdate_buffer_req: Unsupported color conversion");
9354        return false;
9355    }
9356
9357    c2d.close();
9358    status = c2d.open(omx->drv_ctx.video_resolution.frame_height,
9359            omx->drv_ctx.video_resolution.frame_width,
9360            YCbCr420Tile,YCbCr420P);
9361
9362    if (status) {
9363        status = c2d.get_buffer_size(C2D_INPUT,src_size);
9364
9365        if (status)
9366            status = c2d.get_buffer_size(C2D_OUTPUT,destination_size);
9367    }
9368
9369    if (status) {
9370        if (!src_size || src_size > omx->drv_ctx.op_buf.buffer_size ||
9371                !destination_size) {
9372            DEBUG_PRINT_ERROR("\nERROR: Size mismatch in C2D src_size %d"
9373                    "driver size %d destination size %d",
9374                    src_size,omx->drv_ctx.op_buf.buffer_size,destination_size);
9375            status = false;
9376            c2d.close();
9377            buffer_size_req = 0;
9378        } else {
9379            buffer_size_req = destination_size;
9380
9381            if (buffer_size_req < omx->drv_ctx.op_buf.buffer_size)
9382                buffer_size_req = omx->drv_ctx.op_buf.buffer_size;
9383
9384            if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9385                buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9386        }
9387    }
9388
9389    return status;
9390}
9391
9392bool omx_vdec::allocate_color_convert_buf::set_color_format(
9393        OMX_COLOR_FORMATTYPE dest_color_format)
9394{
9395    bool status = true;
9396    OMX_COLOR_FORMATTYPE drv_color_format;
9397
9398    if (!omx) {
9399        DEBUG_PRINT_ERROR("\n Invalid client in color convert");
9400        return false;
9401    }
9402
9403    if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2)
9404        drv_color_format = (OMX_COLOR_FORMATTYPE)
9405            QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
9406    else {
9407        DEBUG_PRINT_ERROR("\n Incorrect color format");
9408        status = false;
9409    }
9410
9411    if (status && (drv_color_format != dest_color_format)) {
9412        DEBUG_PRINT_ERROR("");
9413
9414        if (dest_color_format != OMX_COLOR_FormatYUV420Planar) {
9415            DEBUG_PRINT_ERROR("\n Unsupported color format for c2d");
9416            status = false;
9417        } else {
9418            ColorFormat = OMX_COLOR_FormatYUV420Planar;
9419
9420            if (enabled)
9421                c2d.destroy();
9422
9423            enabled = false;
9424
9425            if (!c2d.init()) {
9426                DEBUG_PRINT_ERROR("\n open failed for c2d");
9427                status = false;
9428            } else
9429                enabled = true;
9430        }
9431    } else {
9432        if (enabled)
9433            c2d.destroy();
9434
9435        enabled = false;
9436    }
9437
9438    return status;
9439}
9440
9441OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
9442{
9443    if (!omx) {
9444        DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9445        return NULL;
9446    }
9447
9448    if (!enabled)
9449        return omx->m_out_mem_ptr;
9450
9451    return m_out_mem_ptr_client;
9452}
9453
9454    OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr
9455(OMX_BUFFERHEADERTYPE *bufadd)
9456{
9457    if (!omx) {
9458        DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9459        return NULL;
9460    }
9461
9462    if (!enabled)
9463        return bufadd;
9464
9465    unsigned index = 0;
9466    index = bufadd - omx->m_out_mem_ptr;
9467
9468    if (index < omx->drv_ctx.op_buf.actualcount) {
9469        m_out_mem_ptr_client[index].nFlags = (bufadd->nFlags & OMX_BUFFERFLAG_EOS);
9470        m_out_mem_ptr_client[index].nTimeStamp = bufadd->nTimeStamp;
9471        bool status;
9472
9473        if (!omx->in_reconfig && !omx->output_flush_progress) {
9474            status = c2d.convert(omx->drv_ctx.ptr_outputbuffer[index].pmem_fd,
9475                    bufadd->pBuffer,pmem_fd[index],pmem_baseaddress[index]);
9476            m_out_mem_ptr_client[index].nFilledLen = buffer_size_req;
9477
9478            if (!status) {
9479                DEBUG_PRINT_ERROR("\n Failed color conversion %d", status);
9480                return NULL;
9481            }
9482        } else
9483            m_out_mem_ptr_client[index].nFilledLen = 0;
9484
9485        return &m_out_mem_ptr_client[index];
9486    }
9487
9488    DEBUG_PRINT_ERROR("\n Index messed up in the get_il_buf_hdr");
9489    return NULL;
9490}
9491
9492    OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_dr_buf_hdr
9493(OMX_BUFFERHEADERTYPE *bufadd)
9494{
9495    if (!omx) {
9496        DEBUG_PRINT_ERROR("\n Invalid param get_buf_hdr");
9497        return NULL;
9498    }
9499
9500    if (!enabled)
9501        return bufadd;
9502
9503    unsigned index = 0;
9504    index = bufadd - m_out_mem_ptr_client;
9505
9506    if (index < omx->drv_ctx.op_buf.actualcount) {
9507        return &omx->m_out_mem_ptr[index];
9508    }
9509
9510    DEBUG_PRINT_ERROR("\n Index messed up in the get_dr_buf_hdr");
9511    return NULL;
9512}
9513    bool omx_vdec::allocate_color_convert_buf::get_buffer_req
9514(unsigned int &buffer_size)
9515{
9516    if (!enabled)
9517        buffer_size = omx->drv_ctx.op_buf.buffer_size;
9518    else if (!c2d.get_buffer_size(C2D_OUTPUT,buffer_size)) {
9519        DEBUG_PRINT_ERROR("\n Get buffer size failed");
9520        return false;
9521    }
9522
9523    if (buffer_size < omx->drv_ctx.op_buf.buffer_size)
9524        buffer_size = omx->drv_ctx.op_buf.buffer_size;
9525
9526    if (buffer_alignment_req < omx->drv_ctx.op_buf.alignment)
9527        buffer_alignment_req = omx->drv_ctx.op_buf.alignment;
9528
9529    return true;
9530}
9531OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::free_output_buffer(
9532        OMX_BUFFERHEADERTYPE *bufhdr)
9533{
9534    unsigned int index = 0;
9535
9536    if (!enabled)
9537        return omx->free_output_buffer(bufhdr);
9538
9539    if (enabled && omx->is_component_secure())
9540        return OMX_ErrorNone;
9541
9542    if (!allocated_count || !bufhdr) {
9543        DEBUG_PRINT_ERROR("\n Color convert no buffer to be freed %p",bufhdr);
9544        return OMX_ErrorBadParameter;
9545    }
9546
9547    index = bufhdr - m_out_mem_ptr_client;
9548
9549    if (index >= omx->drv_ctx.op_buf.actualcount) {
9550        DEBUG_PRINT_ERROR("\n Incorrect index color convert free_output_buffer");
9551        return OMX_ErrorBadParameter;
9552    }
9553
9554    if (pmem_fd[index] > 0) {
9555        munmap(pmem_baseaddress[index], buffer_size_req);
9556        close(pmem_fd[index]);
9557    }
9558
9559    pmem_fd[index] = -1;
9560    omx->free_ion_memory(&op_buf_ion_info[index]);
9561    m_heap_ptr[index].video_heap_ptr = NULL;
9562
9563    if (allocated_count > 0)
9564        allocated_count--;
9565    else
9566        allocated_count = 0;
9567
9568    if (!allocated_count) {
9569        c2d.close();
9570        init_members();
9571    }
9572
9573    return omx->free_output_buffer(&omx->m_out_mem_ptr[index]);
9574}
9575
9576OMX_ERRORTYPE omx_vdec::allocate_color_convert_buf::allocate_buffers_color_convert(OMX_HANDLETYPE hComp,
9577        OMX_BUFFERHEADERTYPE **bufferHdr,OMX_U32 port,OMX_PTR appData,OMX_U32 bytes)
9578{
9579    OMX_ERRORTYPE eRet = OMX_ErrorNone;
9580
9581    if (!enabled) {
9582        eRet = omx->allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
9583        return eRet;
9584    }
9585
9586    if (enabled && omx->is_component_secure()) {
9587        DEBUG_PRINT_ERROR("\nNotin color convert mode secure_mode %d",
9588                omx->is_component_secure());
9589        return OMX_ErrorUnsupportedSetting;
9590    }
9591
9592    if (!bufferHdr || bytes > buffer_size_req) {
9593        DEBUG_PRINT_ERROR("\n Invalid params allocate_buffers_color_convert %p", bufferHdr);
9594        DEBUG_PRINT_ERROR("\n color_convert buffer_size_req %d bytes %d",
9595                buffer_size_req,bytes);
9596        return OMX_ErrorBadParameter;
9597    }
9598
9599    if (allocated_count >= omx->drv_ctx.op_buf.actualcount) {
9600        DEBUG_PRINT_ERROR("\n Actual count err in allocate_buffers_color_convert");
9601        return OMX_ErrorInsufficientResources;
9602    }
9603
9604    OMX_BUFFERHEADERTYPE *temp_bufferHdr = NULL;
9605    eRet = omx->allocate_output_buffer(hComp,&temp_bufferHdr,
9606            port,appData,omx->drv_ctx.op_buf.buffer_size);
9607
9608    if (eRet != OMX_ErrorNone || !temp_bufferHdr) {
9609        DEBUG_PRINT_ERROR("\n Buffer allocation failed color_convert");
9610        return eRet;
9611    }
9612
9613    if ((temp_bufferHdr - omx->m_out_mem_ptr) >=
9614            omx->drv_ctx.op_buf.actualcount) {
9615        DEBUG_PRINT_ERROR("\n Invalid header index %d",
9616                (temp_bufferHdr - omx->m_out_mem_ptr));
9617        return OMX_ErrorUndefined;
9618    }
9619
9620    unsigned int i = allocated_count;
9621    op_buf_ion_info[i].ion_device_fd = omx->alloc_map_ion_memory(
9622            buffer_size_req,buffer_alignment_req,
9623            &op_buf_ion_info[i].ion_alloc_data,&op_buf_ion_info[i].fd_ion_data,
9624            ION_FLAG_CACHED);
9625
9626    pmem_fd[i] = op_buf_ion_info[i].fd_ion_data.fd;
9627
9628    if (op_buf_ion_info[i].ion_device_fd < 0) {
9629        DEBUG_PRINT_ERROR("\n alloc_map_ion failed in color_convert");
9630        return OMX_ErrorInsufficientResources;
9631    }
9632
9633    pmem_baseaddress[i] = (unsigned char *)mmap(NULL,buffer_size_req,
9634            PROT_READ|PROT_WRITE,MAP_SHARED,pmem_fd[i],0);
9635
9636    if (pmem_baseaddress[i] == MAP_FAILED) {
9637        DEBUG_PRINT_ERROR("\n MMAP failed for Size %d",buffer_size_req);
9638        close(pmem_fd[i]);
9639        omx->free_ion_memory(&op_buf_ion_info[i]);
9640        return OMX_ErrorInsufficientResources;
9641    }
9642
9643    m_heap_ptr[i].video_heap_ptr = new VideoHeap (
9644            op_buf_ion_info[i].ion_device_fd,buffer_size_req,
9645            pmem_baseaddress[i],op_buf_ion_info[i].ion_alloc_data.handle,pmem_fd[i]);
9646    m_pmem_info_client[i].pmem_fd = (OMX_U32)m_heap_ptr[i].video_heap_ptr.get();
9647    m_pmem_info_client[i].offset = 0;
9648    m_platform_entry_client[i].entry = (void *)&m_pmem_info_client[i];
9649    m_platform_entry_client[i].type = OMX_QCOM_PLATFORM_PRIVATE_PMEM;
9650    m_platform_list_client[i].nEntries = 1;
9651    m_platform_list_client[i].entryList = &m_platform_entry_client[i];
9652    m_out_mem_ptr_client[i].pOutputPortPrivate = NULL;
9653    m_out_mem_ptr_client[i].nAllocLen = buffer_size_req;
9654    m_out_mem_ptr_client[i].nFilledLen = 0;
9655    m_out_mem_ptr_client[i].nFlags = 0;
9656    m_out_mem_ptr_client[i].nOutputPortIndex = OMX_CORE_OUTPUT_PORT_INDEX;
9657    m_out_mem_ptr_client[i].nSize = sizeof(OMX_BUFFERHEADERTYPE);
9658    m_out_mem_ptr_client[i].nVersion.nVersion = OMX_SPEC_VERSION;
9659    m_out_mem_ptr_client[i].pPlatformPrivate = &m_platform_list_client[i];
9660    m_out_mem_ptr_client[i].pBuffer = pmem_baseaddress[i];
9661    m_out_mem_ptr_client[i].pAppPrivate = appData;
9662    *bufferHdr = &m_out_mem_ptr_client[i];
9663    DEBUG_PRINT_ERROR("\n IL client buffer header %p", *bufferHdr);
9664    allocated_count++;
9665    return eRet;
9666}
9667
9668bool omx_vdec::is_component_secure()
9669{
9670    return secure_mode;
9671}
9672
9673bool omx_vdec::allocate_color_convert_buf::get_color_format(OMX_COLOR_FORMATTYPE &dest_color_format)
9674{
9675    bool status = true;
9676
9677    if (!enabled) {
9678        if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_TILE_4x2)
9679            dest_color_format =  (OMX_COLOR_FORMATTYPE)
9680                QOMX_COLOR_FormatYUV420PackedSemiPlanar64x32Tile2m8ka;
9681        else if (omx->drv_ctx.output_format == VDEC_YUV_FORMAT_NV12)
9682            dest_color_format = OMX_COLOR_FormatYUV420SemiPlanar;
9683        else
9684            status = false;
9685    } else {
9686        if (ColorFormat != OMX_COLOR_FormatYUV420Planar) {
9687            status = false;
9688        } else
9689            dest_color_format = OMX_COLOR_FormatYUV420Planar;
9690    }
9691
9692    return status;
9693}
9694