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