Home | History | Annotate | Download | only in src
      1 /*--------------------------------------------------------------------------
      2 Copyright (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 
     18 THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
     19 WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
     20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
     21 ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
     22 BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
     23 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
     24 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
     25 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
     26 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
     27 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
     28 IF 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
     92 FILE *inputBufferFile1;
     93 char inputfilename [INPUT_BUFFER_FILE_NAME_LEN] = "\0";
     94 #endif
     95 #ifdef OUTPUT_BUFFER_LOG
     96 FILE *outputBufferFile1;
     97 char outputfilename [] = "/data/output.yuv";
     98 #endif
     99 #ifdef OUTPUT_EXTRADATA_LOG
    100 FILE *outputExtradataFile;
    101 char 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_
    150 extern "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 
    164 void* 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("ERESTARTSYS received in ioctl read next msg!");
    182         } else if (error_code < 0) {
    183             DEBUG_PRINT_ERROR("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("ERROR:Wrong ioctl message");
    188         }
    189     }
    190 
    191     DEBUG_PRINT_HIGH("omx_vdec: Async thread stop");
    192     return NULL;
    193 }
    194 
    195 void* 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("ERROR: 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 
    226 void 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
    235 omx_vdec::omx_cmd_queue::~omx_cmd_queue()
    236 {
    237     // Nothing to do
    238 }
    239 
    240 // omx cmd queue constructor
    241 omx_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
    247 bool 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("ERROR: %s()::Command Queue Full", __func__);
    264     }
    265 
    266     return ret;
    267 }
    268 
    269 // omx cmd queue pop
    270 bool 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
    293 unsigned omx_vdec::omx_cmd_queue::get_q_msg_type()
    294 {
    295     return m_q[m_read].id;
    296 }
    297 
    298 #ifdef _ANDROID_
    299 omx_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 }
    304 omx_vdec::ts_arr_list::~ts_arr_list()
    305 {
    306     //free m_ts_arr_list?
    307 }
    308 
    309 bool 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 
    335 bool 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 
    375 bool 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
    391 void *get_omx_component_factory_fn(void)
    392 {
    393     return (new omx_vdec);
    394 }
    395 
    396 #ifdef _ANDROID_
    397 #ifdef USE_ION
    398 VideoHeap::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
    407 VideoHeap::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    ========================================================================== */
    427 omx_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    ========================================================================== */
    569 omx_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    ========================================================================== */
    627 void 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("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("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("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("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("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("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("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("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("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("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("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("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("OMX_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("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("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("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("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("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("VDEC_IOCTL_CMD_PAUSE failed");
    956                                     pThis->omx_report_error ();
    957                                 }
    958                             }
    959                         }
    960                     } else {
    961                         DEBUG_PRINT_ERROR("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("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("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("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    ========================================================================== */
   1149 OMX_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("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("ERROR:Unknown Component");
   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("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("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("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("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("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("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("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("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("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("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("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));
   1594 cleanup:
   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    ========================================================================== */
   1629 OMX_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("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    ========================================================================== */
   1664 OMX_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("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("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    ========================================================================== */
   1704 OMX_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("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");
   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");
   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");
   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)",\
   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("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");
   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");
   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("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");
   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",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("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("send_command_proxy(): Executing --> Loaded");
   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("send_command_proxy(): Executing --> WaitForResources");
   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("send_command_proxy(): Executing --> Executing");
   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("send_command_proxy(): Executing --> Invalid");
   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",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("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("Pause --> loaded");
   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("Pause --> WaitForResources");
   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("Pause --> Pause");
   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("Pause --> Invalid");
   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",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");
   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");
   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");
   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");
   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)",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");
   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)",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    ========================================================================== */
   2187 bool 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("Flush Port (%d) Failed ", (int)flush_dir);
   2213         bRet = false;
   2214     }
   2215 
   2216     return bRet;
   2217 }
   2218 /*=========================================================================
   2219 FUNCTION : execute_output_flush
   2220 
   2221 DESCRIPTION
   2222 Executes the OMX flush at OUTPUT PORT.
   2223 
   2224 PARAMETERS
   2225 None.
   2226 
   2227 RETURN VALUE
   2228 true/false
   2229 ==========================================================================*/
   2230 bool 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 /*=========================================================================
   2266 FUNCTION : execute_input_flush
   2267 
   2268 DESCRIPTION
   2269 Executes the OMX flush at INPUT PORT.
   2270 
   2271 PARAMETERS
   2272 None.
   2273 
   2274 RETURN VALUE
   2275 true/false
   2276 ==========================================================================*/
   2277 bool 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    ========================================================================== */
   2385 bool 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
   2414 OMX_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", 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", 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", profileLevelType->nPortIndex);
   2460         eRet = OMX_ErrorBadPortIndex;
   2461     }
   2462 
   2463     return eRet;
   2464 }
   2465 #endif
   2466 #ifdef MAX_RES_1080P
   2467 OMX_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", 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", 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", profileLevelType->nProfileIndex);
   2519                 eRet = OMX_ErrorNoMore;
   2520             }
   2521         } else {
   2522             DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported ret NoMore");
   2523             eRet = OMX_ErrorNoMore;
   2524         }
   2525     } else {
   2526         DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d", 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    ========================================================================== */
   2548 OMX_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");
   2558         return OMX_ErrorInvalidState;
   2559     }
   2560 
   2561     if (paramData == NULL) {
   2562         DEBUG_PRINT_ERROR("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");
   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");
   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");
   2631                         eRet =  OMX_ErrorNoMore;
   2632                     }
   2633                 } else {
   2634                     DEBUG_PRINT_ERROR("get_parameter: Bad port index %d",
   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");
   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");
   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",
   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",
   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");
   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");
   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",
   2727                         paramIndex);
   2728                 break;
   2729             }
   2730         case OMX_IndexParamVideoH263:
   2731             {
   2732                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263 %08x",
   2733                         paramIndex);
   2734                 break;
   2735             }
   2736         case OMX_IndexParamVideoMpeg4:
   2737             {
   2738                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4 %08x",
   2739                         paramIndex);
   2740                 break;
   2741             }
   2742         case OMX_IndexParamVideoMpeg2:
   2743             {
   2744                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg2 %08x",
   2745                         paramIndex);
   2746                 break;
   2747             }
   2748         case OMX_IndexParamVideoProfileLevelQuerySupported:
   2749             {
   2750                 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported %08x", 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("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", 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_)
   2820 OMX_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    ========================================================================== */
   2878 OMX_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");
   2887         return OMX_ErrorInvalidState;
   2888     }
   2889 
   2890     if (paramData == NULL) {
   2891         DEBUG_PRINT_ERROR("Get Param in Invalid paramData");
   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");
   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("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)",
   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("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)",
   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("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("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",
   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");
   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", 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", 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", 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", 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", 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", comp_role->cRole);
   3194                         eRet =OMX_ErrorUnsupportedSetting;
   3195                     }
   3196                 } else {
   3197                     DEBUG_PRINT_ERROR("Setparameter: unknown param %s", 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");
   3208                     return OMX_ErrorIncorrectStateOperation;
   3209                 }
   3210 
   3211                 OMX_PRIORITYMGMTTYPE *priorityMgmtype = (OMX_PRIORITYMGMTTYPE*) paramData;
   3212                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamPriorityMgmt %d",
   3213                         priorityMgmtype->nGroupID);
   3214 
   3215                 DEBUG_PRINT_LOW("set_parameter: priorityMgmtype %d",
   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",
   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",
   3243                         paramIndex);
   3244                 break;
   3245             }
   3246         case OMX_IndexParamVideoH263:
   3247             {
   3248                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoH263 %d",
   3249                         paramIndex);
   3250                 break;
   3251             }
   3252         case OMX_IndexParamVideoMpeg4:
   3253             {
   3254                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg4 %d",
   3255                         paramIndex);
   3256                 break;
   3257             }
   3258         case OMX_IndexParamVideoMpeg2:
   3259             {
   3260                 DEBUG_PRINT_LOW("set_parameter: OMX_IndexParamVideoMpeg2 %d",
   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",
   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("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("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", 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    ========================================================================== */
   3497 OMX_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");
   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");
   3526                         eRet = OMX_ErrorNoMore;
   3527                     }
   3528 
   3529                 } else {
   3530                     DEBUG_PRINT_ERROR("get_config: Bad port index %d queried on only o/p port",
   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",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    ========================================================================== */
   3601 OMX_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");
   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");
   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");
   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");
   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");
   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");
   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    ========================================================================== */
   3754 OMX_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");
   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", 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", 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    ========================================================================== */
   3805 OMX_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    ========================================================================== */
   3827 OMX_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");
   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    ========================================================================== */
   3851 OMX_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");
   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");
   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("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("Invalid appData or bytes");
   4032                     return OMX_ErrorBadParameter;
   4033                 }
   4034 
   4035                 if (!secure_mode && !buffer) {
   4036                     DEBUG_PRINT_ERROR("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("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("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    ========================================================================== */
   4119 OMX_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("ERROR: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    ========================================================================== */
   4183 OMX_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");
   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",(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 
   4247 OMX_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 
   4263 OMX_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("VDEC_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 
   4320 OMX_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("free_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("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 
   4414 OMX_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("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("ERROR: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    ========================================================================== */
   4501 OMX_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("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("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("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("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("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("ERROR: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    ========================================================================== */
   4688 OMX_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");
   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");
   4846                     return OMX_ErrorInsufficientResources;
   4847                 }
   4848             }
   4849 
   4850 #endif
   4851         } else {
   4852             DEBUG_PRINT_ERROR("Output buf mem alloc failed[0x%x][0x%x]",\
   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("ERROR: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("ERROR: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("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("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("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("ERROR: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    ========================================================================== */
   5030 OMX_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");
   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",(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    ========================================================================== */
   5109 OMX_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");
   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");
   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");
   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");
   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    ========================================================================== */
   5259 OMX_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");
   5274         return OMX_ErrorInvalidState;
   5275     }
   5276 
   5277     if (buffer == NULL) {
   5278         DEBUG_PRINT_ERROR("ERROR:ETB Buffer is NULL");
   5279         return OMX_ErrorBadParameter;
   5280     }
   5281 
   5282     if (!m_inp_bEnabled) {
   5283         DEBUG_PRINT_ERROR("ERROR: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("ERROR: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("ERROR: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("ERROR: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    ========================================================================== */
   5365 OMX_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("ERROR: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("ERROR: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("ERROR: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    ========================================================================== */
   5578 OMX_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");
   5584         return OMX_ErrorInvalidState;
   5585     }
   5586 
   5587     if (!m_out_bEnabled) {
   5588         DEBUG_PRINT_ERROR("ERROR: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("ERROR: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    ========================================================================== */
   5621 OMX_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("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    ========================================================================== */
   5727 OMX_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    ========================================================================== */
   5753 OMX_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",\
   5771                 m_state);
   5772         DEBUG_PRINT_ERROR("Playback 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    ========================================================================== */
   5931 OMX_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("");
   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");
   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",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");
   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    ========================================================================== */
   6017 OMX_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("ERROR: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    ========================================================================== */
   6109 bool 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    ========================================================================== */
   6138 bool 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    ========================================================================== */
   6180 bool 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    ========================================================================== */
   6222 bool 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    ========================================================================== */
   6250 bool 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    ========================================================================== */
   6289 bool 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 
   6313 OMX_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("[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("");
   6337             DEBUG_PRINT_HIGH("***************************************************");
   6338             DEBUG_PRINT_HIGH("FillBufferDone: End Of Sequence Received");
   6339             DEBUG_PRINT_HIGH("***************************************************");
   6340         }
   6341 
   6342         if (buffer->nFlags & OMX_BUFFERFLAG_DATACORRUPT) {
   6343             DEBUG_PRINT_HIGH("");
   6344             DEBUG_PRINT_HIGH("***************************************************");
   6345             DEBUG_PRINT_HIGH("FillBufferDone: OMX_BUFFERFLAG_DATACORRUPT Received");
   6346             DEBUG_PRINT_HIGH("***************************************************");
   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 
   6504 OMX_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("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("ERROR: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 
   6546 int 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("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("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 
   6736 OMX_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 
   6779 OMX_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("Pushing input Buffer Failed");
   6832             omx_report_error ();
   6833             break;
   6834         }
   6835     }
   6836 
   6837     return ret;
   6838 }
   6839 
   6840 OMX_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("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("Zero 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("ERROR: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 
   6953 OMX_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("ERROR: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("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("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("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("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("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("ERROR: 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("ERROR: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 
   7206 OMX_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("Invalid 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("Destination 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("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("Unsupported VC1 profile in ArbitraryBytes Mode");
   7260             return OMX_ErrorBadParameter;
   7261     }
   7262 
   7263     return OMX_ErrorNone;
   7264 }
   7265 
   7266 #ifndef USE_ION
   7267 bool 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("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
   7289 int 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");
   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", 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->ION_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->ION_HEAP_MASK = ION_HEAP(ION_IOMMU_HEAP_ID);
   7330         } else {
   7331             alloc_data->ION_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->ION_HEAP_MASK = ION_HEAP(MEM_HEAP_ID);
   7338 #else
   7339         alloc_data->ION_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("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("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 
   7374 void omx_vdec::free_ion_memory(struct vdec_ion *buf_ion_info)
   7375 {
   7376 
   7377     if (!buf_ion_info) {
   7378         DEBUG_PRINT_ERROR("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("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
   7398 void 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 
   7435 void 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 
   7482 OMX_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 
   7538 OMX_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 
   7570 OMX_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 
   7603 OMX_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 
   7618 OMX_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");
   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");
   7653             return OMX_ErrorHardware;
   7654         }
   7655 
   7656         if (!client_buffers.update_buffer_req()) {
   7657             DEBUG_PRINT_ERROR("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("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("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 
   7710 OMX_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]",\
   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 
   7853 void 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("ERROR: empty_buffer_done() failed!");
   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("ERROR: fill_buffer_done() failed!");
   7915                     omx_report_error ();
   7916                 }
   7917 
   7918                 break;
   7919         }
   7920     }
   7921 }
   7922 
   7923 void 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 
   7956 void 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 
   7981 void 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("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 
   8177 void 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("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 
   8369 OMX_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("Set 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 
   8452 OMX_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 
   8474 void 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 =============="
   8483             "           Size: %u"
   8484             "        Version: %u"
   8485             "      PortIndex: %u"
   8486             "           Type: %x"
   8487             "       DataSize: %u",
   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 ------"
   8495                 "                Size: %u"
   8496                 "             Version: %u"
   8497                 "           PortIndex: %u"
   8498                 " Is Interlace Format: %u"
   8499                 "   Interlace Formats: %u"
   8500                 "=========== End of Interlace ===========",
   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 --------"
   8508                 "             Picture Type: %u"
   8509                 "           Interlace Type: %u"
   8510                 " Pan Scan Total Frame Num: %u"
   8511                 "   Concealed Macro Blocks: %u"
   8512                 "               frame rate: %u"
   8513                 "           Aspect Ratio X: %u"
   8514                 "           Aspect Ratio Y: %u",
   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                     "------------------------------"
   8526                     "     Pan Scan Frame Num: %d"
   8527                     "            Rectangle x: %d"
   8528                     "            Rectangle y: %d"
   8529                     "           Rectangle dx: %d"
   8530                     "           Rectangle dy: %d",
   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 
   8545 void 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 
   8598 void 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 
   8653 void 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 
   8723 void 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 
   8740 void 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 
   8753 void 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 
   8766 void 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 
   8777 OMX_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("ERROR: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("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("desc buffer Allocation failed ");
   8801         return OMX_ErrorInsufficientResources;
   8802     }
   8803 
   8804     return eRet;
   8805 }
   8806 
   8807 void 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 
   8818 void 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 
   8854 OMX_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 
   8944 OMX_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("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",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");
   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 
   9052 void 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 
   9080 OMX_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("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("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",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");
   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 
   9188 void 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_
   9213 OMX_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("ERROR :iDivXDrmDecrypt->Init %d", err);
   9223             delete iDivXDrmDecrypt;
   9224             iDivXDrmDecrypt = NULL;
   9225         }
   9226     } else {
   9227         DEBUG_PRINT_ERROR("Unable to Create DIVX DRM");
   9228         err = OMX_ErrorUndefined;
   9229     }
   9230 
   9231     return err;
   9232 }
   9233 #endif //_ANDROID_
   9234 
   9235 OMX_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 
   9273 OMX_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 }
   9302 omx_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 
   9310 void omx_vdec::allocate_color_convert_buf::set_vdec_client(void *client)
   9311 {
   9312     omx = reinterpret_cast<omx_vdec*>(client);
   9313 }
   9314 
   9315 void 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 
   9330 omx_vdec::allocate_color_convert_buf::~allocate_color_convert_buf()
   9331 {
   9332     c2d.destroy();
   9333 }
   9334 
   9335 bool 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("Invalid client in color convert");
   9343         return false;
   9344     }
   9345 
   9346     if (!enabled) {
   9347         DEBUG_PRINT_ERROR("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("update_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("ERROR: 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 
   9392 bool 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("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("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("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("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 
   9441 OMX_BUFFERHEADERTYPE* omx_vdec::allocate_color_convert_buf::get_il_buf_hdr()
   9442 {
   9443     if (!omx) {
   9444         DEBUG_PRINT_ERROR("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("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("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("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("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("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("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 }
   9531 OMX_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("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("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 
   9576 OMX_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("Notin 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("Invalid params allocate_buffers_color_convert %p", bufferHdr);
   9594         DEBUG_PRINT_ERROR("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("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("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("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("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("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("IL client buffer header %p", *bufferHdr);
   9664     allocated_count++;
   9665     return eRet;
   9666 }
   9667 
   9668 bool omx_vdec::is_component_secure()
   9669 {
   9670     return secure_mode;
   9671 }
   9672 
   9673 bool 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