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