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