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