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