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