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