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