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