1 /*--------------------------------------------------------------------------
2 Copyright (c) 2010-2012, 2015 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 O p e n M A X w r a p p e r s
30 O p e n M A X C o r e
31
32 *//** @file omx_video_base.cpp
33 This module contains the implementation of the OpenMAX core & component.
34
35 *//*========================================================================*/
36
37 //////////////////////////////////////////////////////////////////////////////
38 // Include Files
39 //////////////////////////////////////////////////////////////////////////////
40
41 #include <string.h>
42 #include "omx_video_base.h"
43 #include <stdlib.h>
44 #include <errno.h>
45 #include <fcntl.h>
46 #include <unistd.h>
47 #include <sys/prctl.h>
48 #ifdef _ANDROID_ICS_
49 #include <media/hardware/HardwareAPI.h>
50 #include <gralloc_priv.h>
51 #endif
52 #ifndef _ANDROID_
53 #include <glib.h>
54 #define strlcpy g_strlcpy
55 #endif
56 #define H264_SUPPORTED_WIDTH (480)
57 #define H264_SUPPORTED_HEIGHT (368)
58
59 #define MPEG4_SUPPORTED_WIDTH (480)
60 #define MPEG4_SUPPORTED_HEIGHT (368)
61
62 #define VC1_SP_MP_START_CODE 0xC5000000
63 #define VC1_SP_MP_START_CODE_MASK 0xFF000000
64 #define VC1_AP_START_CODE 0x00000100
65 #define VC1_AP_START_CODE_MASK 0xFFFFFF00
66 #define VC1_STRUCT_C_PROFILE_MASK 0xF0
67 #define VC1_STRUCT_B_LEVEL_MASK 0xE0000000
68 #define VC1_SIMPLE_PROFILE 0
69 #define VC1_MAIN_PROFILE 1
70 #define VC1_ADVANCE_PROFILE 3
71 #define VC1_SIMPLE_PROFILE_LOW_LEVEL 0
72 #define VC1_SIMPLE_PROFILE_MED_LEVEL 2
73 #define VC1_STRUCT_C_LEN 4
74 #define VC1_STRUCT_C_POS 8
75 #define VC1_STRUCT_A_POS 12
76 #define VC1_STRUCT_B_POS 24
77 #define VC1_SEQ_LAYER_SIZE 36
78
79 #define IS_NOT_ALIGNED( num, to) (num & (to-1))
80 #define ALIGN( num, to ) (((num) + (to-1)) & (~(to-1)))
81 #define SZ_2K (2048)
82
83 typedef struct OMXComponentCapabilityFlagsType
84 {
85 ////////////////// OMX COMPONENT CAPABILITY RELATED MEMBERS
86 OMX_BOOL iIsOMXComponentMultiThreaded;
87 OMX_BOOL iOMXComponentSupportsExternalOutputBufferAlloc;
88 OMX_BOOL iOMXComponentSupportsExternalInputBufferAlloc;
89 OMX_BOOL iOMXComponentSupportsMovableInputBuffers;
90 OMX_BOOL iOMXComponentSupportsPartialFrames;
91 OMX_BOOL iOMXComponentUsesNALStartCodes;
92 OMX_BOOL iOMXComponentCanHandleIncompleteFrames;
93 OMX_BOOL iOMXComponentUsesFullAVCFrames;
94
95 } OMXComponentCapabilityFlagsType;
96 #define OMX_COMPONENT_CAPABILITY_TYPE_INDEX 0xFF7A347
97 #ifdef OUTPUT_BUFFER_LOG
98 extern FILE *outputBufferFile1;
99 #endif
100
message_thread(void * input)101 void* message_thread(void *input)
102 {
103 omx_video* omx = reinterpret_cast<omx_video*>(input);
104 unsigned char id;
105 int n;
106
107 DEBUG_PRINT_LOW("omx_venc: message thread start\n");
108 prctl(PR_SET_NAME, (unsigned long)"VideoEncMsgThread", 0, 0, 0);
109 while(1)
110 {
111 n = read(omx->m_pipe_in, &id, 1);
112 if(0 == n)
113 {
114 break;
115 }
116
117 if(1 == n)
118 {
119 omx->process_event_cb(omx, id);
120 }
121 #ifdef QLE_BUILD
122 if(n < 0) break;
123 #else
124 if((n < 0) && (errno != EINTR)) break;
125 #endif
126 }
127 DEBUG_PRINT_LOW("omx_venc: message thread stop\n");
128 return 0;
129 }
130
post_message(omx_video * omx,unsigned char id)131 void post_message(omx_video *omx, unsigned char id)
132 {
133 DEBUG_PRINT_LOW("omx_venc: post_message %d\n", id);
134 write(omx->m_pipe_out, &id, 1);
135 }
136
137 // omx_cmd_queue destructor
~omx_cmd_queue()138 omx_video::omx_cmd_queue::~omx_cmd_queue()
139 {
140 // Nothing to do
141 }
142
143 // omx cmd queue constructor
omx_cmd_queue()144 omx_video::omx_cmd_queue::omx_cmd_queue(): m_read(0),m_write(0),m_size(0)
145 {
146 memset(m_q,0,sizeof(omx_event)*OMX_CORE_CONTROL_CMDQ_SIZE);
147 }
148
149 // omx cmd queue insert
insert_entry(unsigned p1,unsigned p2,unsigned id)150 bool omx_video::omx_cmd_queue::insert_entry(unsigned p1, unsigned p2, unsigned id)
151 {
152 bool ret = true;
153 if(m_size < OMX_CORE_CONTROL_CMDQ_SIZE)
154 {
155 m_q[m_write].id = id;
156 m_q[m_write].param1 = p1;
157 m_q[m_write].param2 = p2;
158 m_write++;
159 m_size ++;
160 if(m_write >= OMX_CORE_CONTROL_CMDQ_SIZE)
161 {
162 m_write = 0;
163 }
164 }
165 else
166 {
167 ret = false;
168 DEBUG_PRINT_ERROR("ERROR!!! Command Queue Full\n");
169 }
170 return ret;
171 }
172
173 // omx cmd queue pop
pop_entry(unsigned * p1,unsigned * p2,unsigned * id)174 bool omx_video::omx_cmd_queue::pop_entry(unsigned *p1, unsigned *p2, unsigned *id)
175 {
176 bool ret = true;
177 if(m_size > 0)
178 {
179 *id = m_q[m_read].id;
180 *p1 = m_q[m_read].param1;
181 *p2 = m_q[m_read].param2;
182 // Move the read pointer ahead
183 ++m_read;
184 --m_size;
185 if(m_read >= OMX_CORE_CONTROL_CMDQ_SIZE)
186 {
187 m_read = 0;
188 }
189 }
190 else
191 {
192 ret = false;
193 }
194 return ret;
195 }
196
197 // Retrieve the first mesg type in the queue
get_q_msg_type()198 unsigned omx_video::omx_cmd_queue::get_q_msg_type()
199 {
200 return m_q[m_read].id;
201 }
202
203
204
205 #ifdef _ANDROID_
VideoHeap(int fd,size_t size,void * base)206 VideoHeap::VideoHeap(int fd, size_t size, void* base)
207 {
208 // dup file descriptor, map once, use pmem
209 init(dup(fd), base, size, 0 , MEM_DEVICE);
210 }
211 #endif // _ANDROID_
212
213 /* ======================================================================
214 FUNCTION
215 omx_venc::omx_venc
216
217 DESCRIPTION
218 Constructor
219
220 PARAMETERS
221 None
222
223 RETURN VALUE
224 None.
225 ========================================================================== */
omx_video()226 omx_video::omx_video(): msg_thread_id(0),
227 async_thread_id(0),
228 m_state(OMX_StateInvalid),
229 m_app_data(NULL),
230 m_inp_mem_ptr(NULL),
231 m_out_mem_ptr(NULL),
232 m_pInput_pmem(NULL),
233 m_pOutput_pmem(NULL),
234 #ifdef USE_ION
235 m_pInput_ion(NULL),
236 m_pOutput_ion(NULL),
237 #endif
238 pending_input_buffers(0),
239 pending_output_buffers(0),
240 m_out_bm_count(0),
241 m_inp_bm_count(0),
242 m_flags(0),
243 m_event_port_settings_sent(false),
244 output_flush_progress (false),
245 input_flush_progress (false),
246 input_use_buffer (false),
247 output_use_buffer (false),
248 m_use_input_pmem(OMX_FALSE),
249 m_use_output_pmem(OMX_FALSE),
250 m_etb_count(0),
251 m_fbd_count(0),
252 m_pipe_in(-1),
253 m_pipe_out(-1),
254 m_error_propogated(false),
255 m_input_msg_id(OMX_COMPONENT_GENERATE_ETB),
256 psource_frame(NULL),
257 pdest_frame(NULL),
258 c2d_opened(false),
259 secure_session(false)
260 {
261 DEBUG_PRINT_HIGH("\n omx_video(): Inside Constructor()");
262 memset(&m_cmp,0,sizeof(m_cmp));
263 memset(&m_pCallbacks,0,sizeof(m_pCallbacks));
264 secure_color_format = (int) OMX_COLOR_FormatYUV420SemiPlanar;
265 pthread_mutex_init(&m_lock, NULL);
266 sem_init(&m_cmd_lock,0,0);
267 }
268
269
270 /* ======================================================================
271 FUNCTION
272 omx_venc::~omx_venc
273
274 DESCRIPTION
275 Destructor
276
277 PARAMETERS
278 None
279
280 RETURN VALUE
281 None.
282 ========================================================================== */
~omx_video()283 omx_video::~omx_video()
284 {
285 DEBUG_PRINT_HIGH("\n ~omx_video(): Inside Destructor()");
286 if(m_pipe_in >= 0) close(m_pipe_in);
287 if(m_pipe_out >= 0) close(m_pipe_out);
288 DEBUG_PRINT_HIGH("omx_video: Waiting on Msg Thread exit\n");
289 if (msg_thread_id != 0) {
290 pthread_join(msg_thread_id,NULL);
291 }
292 DEBUG_PRINT_HIGH("omx_video: Waiting on Async Thread exit\n");
293 if (async_thread_id != 0) {
294 pthread_join(async_thread_id,NULL);
295 }
296 pthread_mutex_destroy(&m_lock);
297 sem_destroy(&m_cmd_lock);
298 DEBUG_PRINT_HIGH("\n m_etb_count = %u, m_fbd_count = %u\n", m_etb_count,
299 m_fbd_count);
300 DEBUG_PRINT_HIGH("omx_video: Destructor exit\n");
301 DEBUG_PRINT_HIGH("Exiting 7x30 OMX Video Encoder ...\n");
302 }
303
304 /* ======================================================================
305 FUNCTION
306 omx_venc::OMXCntrlProcessMsgCb
307
308 DESCRIPTION
309 IL Client callbacks are generated through this routine. The decoder
310 provides the thread context for this routine.
311
312 PARAMETERS
313 ctxt -- Context information related to the self.
314 id -- Event identifier. This could be any of the following:
315 1. Command completion event
316 2. Buffer done callback event
317 3. Frame done callback event
318
319 RETURN VALUE
320 None.
321
322 ========================================================================== */
process_event_cb(void * ctxt,unsigned char id)323 void omx_video::process_event_cb(void *ctxt, unsigned char id)
324 {
325 unsigned p1; // Parameter - 1
326 unsigned p2; // Parameter - 2
327 unsigned ident;
328 unsigned qsize=0; // qsize
329 omx_video *pThis = (omx_video *) ctxt;
330
331 if(!pThis)
332 {
333 DEBUG_PRINT_ERROR("ERROR:ProcessMsgCb:Context is incorrect; bailing out\n");
334 return;
335 }
336
337 // Protect the shared queue data structure
338 do
339 {
340 /*Read the message id's from the queue*/
341
342 pthread_mutex_lock(&pThis->m_lock);
343 qsize = pThis->m_cmd_q.m_size;
344 if(qsize)
345 {
346 pThis->m_cmd_q.pop_entry(&p1,&p2,&ident);
347 }
348
349 if(qsize == 0)
350 {
351 qsize = pThis->m_ftb_q.m_size;
352 if(qsize)
353 {
354 pThis->m_ftb_q.pop_entry(&p1,&p2,&ident);
355 }
356 }
357
358 if(qsize == 0)
359 {
360 qsize = pThis->m_etb_q.m_size;
361 if(qsize)
362 {
363 pThis->m_etb_q.pop_entry(&p1,&p2,&ident);
364 }
365 }
366
367 pthread_mutex_unlock(&pThis->m_lock);
368
369 /*process message if we have one*/
370 if(qsize > 0)
371 {
372 id = ident;
373 switch(id)
374 {
375 case OMX_COMPONENT_GENERATE_EVENT:
376 if(pThis->m_pCallbacks.EventHandler)
377 {
378 switch(p1)
379 {
380 case OMX_CommandStateSet:
381 pThis->m_state = (OMX_STATETYPE) p2;
382 DEBUG_PRINT_LOW("Process -> state set to %d \n", pThis->m_state);
383 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
384 OMX_EventCmdComplete, p1, p2, NULL);
385 break;
386
387 case OMX_EventError:
388 DEBUG_PRINT_ERROR("\nERROR: OMX_EventError: p2 = %d\n", p2);
389 if(p2 == OMX_ErrorHardware)
390 {
391 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
392 OMX_EventError,OMX_ErrorHardware,0,NULL);
393 }
394 else
395 {
396 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
397 OMX_EventError, p2, NULL, NULL );
398
399 }
400 break;
401
402 case OMX_CommandPortDisable:
403 DEBUG_PRINT_LOW("Process -> Port %d set to PORT_STATE_DISABLED" \
404 "state \n", p2);
405 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
406 OMX_EventCmdComplete, p1, p2, NULL );
407 break;
408 case OMX_CommandPortEnable:
409 DEBUG_PRINT_LOW("Process ->Port %d set PORT_STATE_ENABLED state\n" \
410 , p2);
411 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,\
412 OMX_EventCmdComplete, p1, p2, NULL );
413 break;
414
415 default:
416 DEBUG_PRINT_LOW("\n process_event_cb forwarding EventCmdComplete %d \n", p1);
417 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
418 OMX_EventCmdComplete, p1, p2, NULL );
419 break;
420
421 }
422 }
423 else
424 {
425 DEBUG_PRINT_ERROR("ERROR: ProcessMsgCb NULL callbacks\n");
426 }
427 break;
428 case OMX_COMPONENT_GENERATE_ETB_OPQ:
429 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB_OPQ\n");
430 if(pThis->empty_this_buffer_opaque((OMX_HANDLETYPE)p1,\
431 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
432 {
433 DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
434 pThis->omx_report_error ();
435 }
436 break;
437 case OMX_COMPONENT_GENERATE_ETB:
438 DEBUG_PRINT_LOW("OMX_COMPONENT_GENERATE_ETB\n");
439 if(pThis->empty_this_buffer_proxy((OMX_HANDLETYPE)p1,\
440 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
441 {
442 DEBUG_PRINT_ERROR("\nERROR: ETBProxy() failed!\n");
443 pThis->omx_report_error ();
444 }
445 break;
446
447 case OMX_COMPONENT_GENERATE_FTB:
448 if( pThis->fill_this_buffer_proxy((OMX_HANDLETYPE)p1,\
449 (OMX_BUFFERHEADERTYPE *)p2) != OMX_ErrorNone)
450 {
451 DEBUG_PRINT_ERROR("\nERROR: FTBProxy() failed!\n");
452 pThis->omx_report_error ();
453 }
454 break;
455
456 case OMX_COMPONENT_GENERATE_COMMAND:
457 pThis->send_command_proxy(&pThis->m_cmp,(OMX_COMMANDTYPE)p1,\
458 (OMX_U32)p2,(OMX_PTR)NULL);
459 break;
460
461 case OMX_COMPONENT_GENERATE_EBD:
462 if( pThis->empty_buffer_done(&pThis->m_cmp,
463 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
464 {
465 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
466 pThis->omx_report_error ();
467 }
468 break;
469
470 case OMX_COMPONENT_GENERATE_FBD:
471 if( pThis->fill_buffer_done(&pThis->m_cmp,
472 (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
473 {
474 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
475 pThis->omx_report_error ();
476 }
477 break;
478
479 case OMX_COMPONENT_GENERATE_EVENT_INPUT_FLUSH:
480
481 pThis->input_flush_progress = false;
482 DEBUG_PRINT_HIGH("\nm_etb_count at i/p flush = %u", m_etb_count);
483 m_etb_count = 0;
484 if(pThis->m_pCallbacks.EventHandler)
485 {
486 /*Check if we need generate event for Flush done*/
487 if(BITMASK_PRESENT(&pThis->m_flags,
488 OMX_COMPONENT_INPUT_FLUSH_PENDING))
489 {
490 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_INPUT_FLUSH_PENDING);
491 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
492 OMX_EventCmdComplete,OMX_CommandFlush,
493 PORT_INDEX_IN,NULL );
494 }
495 else if(BITMASK_PRESENT(&pThis->m_flags,
496 OMX_COMPONENT_IDLE_PENDING))
497 {
498 if(!pThis->output_flush_progress)
499 {
500 DEBUG_PRINT_LOW("\n dev_stop called after input flush complete\n");
501 if(dev_stop() != 0)
502 {
503 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in i/p flush!\n");
504 pThis->omx_report_error ();
505 }
506 }
507 }
508 }
509
510 break;
511
512 case OMX_COMPONENT_GENERATE_EVENT_OUTPUT_FLUSH:
513
514 pThis->output_flush_progress = false;
515 DEBUG_PRINT_HIGH("\nm_fbd_count at o/p flush = %u", m_fbd_count);
516 m_fbd_count = 0;
517 if(pThis->m_pCallbacks.EventHandler)
518 {
519 /*Check if we need generate event for Flush done*/
520 if(BITMASK_PRESENT(&pThis->m_flags,
521 OMX_COMPONENT_OUTPUT_FLUSH_PENDING))
522 {
523 BITMASK_CLEAR (&pThis->m_flags,OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
524
525 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
526 OMX_EventCmdComplete,OMX_CommandFlush,
527 PORT_INDEX_OUT,NULL );
528 }
529 else if(BITMASK_PRESENT(&pThis->m_flags ,OMX_COMPONENT_IDLE_PENDING))
530 {
531 DEBUG_PRINT_LOW("\n dev_stop called after Output flush complete\n");
532 if(!pThis->input_flush_progress)
533 {
534 if(dev_stop() != 0)
535 {
536 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed in o/p flush!\n");
537 pThis->omx_report_error ();
538 }
539 }
540 }
541 }
542 break;
543
544 case OMX_COMPONENT_GENERATE_START_DONE:
545 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE msg");
546
547 if(pThis->m_pCallbacks.EventHandler)
548 {
549 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Success");
550 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
551 {
552 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_START_DONE Move to \
553 executing");
554 // Send the callback now
555 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
556 pThis->m_state = OMX_StateExecuting;
557 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
558 OMX_EventCmdComplete,OMX_CommandStateSet,
559 OMX_StateExecuting, NULL);
560 }
561 else if(BITMASK_PRESENT(&pThis->m_flags,
562 OMX_COMPONENT_PAUSE_PENDING))
563 {
564 if(dev_pause())
565 {
566 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in Start Done!\n");
567 pThis->omx_report_error ();
568 }
569 }
570 else if (BITMASK_PRESENT(&pThis->m_flags,
571 OMX_COMPONENT_LOADED_START_PENDING))
572 {
573 if(dev_loaded_start_done())
574 {
575 DEBUG_PRINT_LOW("successful loaded Start Done!");
576 }
577 else
578 {
579 DEBUG_PRINT_ERROR("ERROR: failed in loaded Start Done!");
580 pThis->omx_report_error ();
581 }
582 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_START_PENDING);
583 }
584 else
585 {
586 DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
587 }
588 }
589 else
590 {
591 DEBUG_PRINT_LOW("\n Event Handler callback is NULL");
592 }
593 break;
594
595 case OMX_COMPONENT_GENERATE_PAUSE_DONE:
596 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_PAUSE_DONE msg");
597 if(pThis->m_pCallbacks.EventHandler)
598 {
599 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_PAUSE_PENDING))
600 {
601 //Send the callback now
602 pThis->complete_pending_buffer_done_cbs();
603 DEBUG_PRINT_LOW("omx_video::process_event_cb() Sending PAUSE complete after all pending EBD/FBD\n");
604 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_PAUSE_PENDING);
605 pThis->m_state = OMX_StatePause;
606 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
607 OMX_EventCmdComplete,OMX_CommandStateSet,
608 OMX_StatePause, NULL);
609 }
610 }
611
612 break;
613
614 case OMX_COMPONENT_GENERATE_RESUME_DONE:
615 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_RESUME_DONE msg");
616 if(pThis->m_pCallbacks.EventHandler)
617 {
618 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_EXECUTE_PENDING))
619 {
620 // Send the callback now
621 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_EXECUTE_PENDING);
622 pThis->m_state = OMX_StateExecuting;
623 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp, pThis->m_app_data,
624 OMX_EventCmdComplete,OMX_CommandStateSet,
625 OMX_StateExecuting,NULL);
626 }
627 }
628
629 break;
630
631 case OMX_COMPONENT_GENERATE_STOP_DONE:
632 DEBUG_PRINT_LOW("\n OMX_COMPONENT_GENERATE_STOP_DONE msg");
633 if(pThis->m_pCallbacks.EventHandler)
634 {
635 pThis->complete_pending_buffer_done_cbs();
636 if(BITMASK_PRESENT(&pThis->m_flags,OMX_COMPONENT_IDLE_PENDING))
637 {
638 // Send the callback now
639 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_IDLE_PENDING);
640 pThis->m_state = OMX_StateIdle;
641 pThis->m_pCallbacks.EventHandler(&pThis->m_cmp,pThis->m_app_data,
642 OMX_EventCmdComplete,OMX_CommandStateSet,
643 OMX_StateIdle,NULL);
644 }
645 else if (BITMASK_PRESENT(&pThis->m_flags,
646 OMX_COMPONENT_LOADED_STOP_PENDING))
647 {
648 if(dev_loaded_stop_done())
649 {
650 DEBUG_PRINT_LOW("successful loaded Stop Done!");
651 }
652 else
653 {
654 DEBUG_PRINT_ERROR("ERROR: failed in loaded Stop Done!");
655 pThis->omx_report_error ();
656 }
657 BITMASK_CLEAR((&pThis->m_flags),OMX_COMPONENT_LOADED_STOP_PENDING);
658 }
659 else
660 {
661 DEBUG_PRINT_ERROR("\nERROR: unknown flags=%x\n",pThis->m_flags);
662 }
663 }
664
665 break;
666
667 case OMX_COMPONENT_GENERATE_HARDWARE_ERROR:
668 DEBUG_PRINT_ERROR("\nERROR: OMX_COMPONENT_GENERATE_HARDWARE_ERROR!\n");
669 pThis->omx_report_error ();
670 break;
671
672 default:
673 DEBUG_PRINT_LOW("\n process_event_cb unknown msg id 0x%02x", id);
674 break;
675 }
676 }
677
678 pthread_mutex_lock(&pThis->m_lock);
679 qsize = pThis->m_cmd_q.m_size + pThis->m_ftb_q.m_size +\
680 pThis->m_etb_q.m_size;
681
682 pthread_mutex_unlock(&pThis->m_lock);
683
684 }
685 while(qsize>0);
686 DEBUG_PRINT_LOW("\n exited the while loop\n");
687
688 }
689
690
691
692
693 /* ======================================================================
694 FUNCTION
695 omx_venc::GetComponentVersion
696
697 DESCRIPTION
698 Returns the component version.
699
700 PARAMETERS
701 TBD.
702
703 RETURN VALUE
704 OMX_ErrorNone.
705
706 ========================================================================== */
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)707 OMX_ERRORTYPE omx_video::get_component_version
708 (
709 OMX_IN OMX_HANDLETYPE hComp,
710 OMX_OUT OMX_STRING componentName,
711 OMX_OUT OMX_VERSIONTYPE* componentVersion,
712 OMX_OUT OMX_VERSIONTYPE* specVersion,
713 OMX_OUT OMX_UUIDTYPE* componentUUID
714 )
715 {
716 if(m_state == OMX_StateInvalid)
717 {
718 DEBUG_PRINT_ERROR("ERROR: Get Comp Version in Invalid State\n");
719 return OMX_ErrorInvalidState;
720 }
721 /* TBD -- Return the proper version */
722 if (specVersion)
723 {
724 specVersion->nVersion = OMX_SPEC_VERSION;
725 }
726 return OMX_ErrorNone;
727 }
728 /* ======================================================================
729 FUNCTION
730 omx_venc::SendCommand
731
732 DESCRIPTION
733 Returns zero if all the buffers released..
734
735 PARAMETERS
736 None.
737
738 RETURN VALUE
739 true/false
740
741 ========================================================================== */
send_command(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)742 OMX_ERRORTYPE omx_video::send_command(OMX_IN OMX_HANDLETYPE hComp,
743 OMX_IN OMX_COMMANDTYPE cmd,
744 OMX_IN OMX_U32 param1,
745 OMX_IN OMX_PTR cmdData
746 )
747 {
748 if(m_state == OMX_StateInvalid)
749 {
750 DEBUG_PRINT_ERROR("ERROR: Send Command in Invalid State\n");
751 return OMX_ErrorInvalidState;
752 }
753
754 if(cmd == OMX_CommandFlush || cmd == OMX_CommandPortDisable || cmd == OMX_CommandPortEnable)
755 {
756 if((param1 != PORT_INDEX_IN) && (param1 != PORT_INDEX_OUT) && (param1 != PORT_INDEX_BOTH))
757 {
758 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index\n");
759 return OMX_ErrorBadPortIndex;
760 }
761 }
762 if(cmd == OMX_CommandMarkBuffer)
763 {
764 if(param1 != PORT_INDEX_IN)
765 {
766 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->bad port index \n");
767 return OMX_ErrorBadPortIndex;
768 }
769 if(!cmdData)
770 {
771 DEBUG_PRINT_ERROR("ERROR: omx_video::send_command-->param is null");
772 return OMX_ErrorBadParameter;
773 }
774 }
775
776 post_event((unsigned)cmd,(unsigned)param1,OMX_COMPONENT_GENERATE_COMMAND);
777 sem_wait(&m_cmd_lock);
778 return OMX_ErrorNone;
779 }
780
781 /* ======================================================================
782 FUNCTION
783 omx_venc::SendCommand
784
785 DESCRIPTION
786 Returns zero if all the buffers released..
787
788 PARAMETERS
789 None.
790
791 RETURN VALUE
792 true/false
793
794 ========================================================================== */
send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_COMMANDTYPE cmd,OMX_IN OMX_U32 param1,OMX_IN OMX_PTR cmdData)795 OMX_ERRORTYPE omx_video::send_command_proxy(OMX_IN OMX_HANDLETYPE hComp,
796 OMX_IN OMX_COMMANDTYPE cmd,
797 OMX_IN OMX_U32 param1,
798 OMX_IN OMX_PTR cmdData
799 )
800 {
801 OMX_ERRORTYPE eRet = OMX_ErrorNone;
802 OMX_STATETYPE eState = (OMX_STATETYPE) param1;
803 int bFlag = 1;
804
805 if(cmd == OMX_CommandStateSet)
806 {
807 /***************************/
808 /* Current State is Loaded */
809 /***************************/
810 if(m_state == OMX_StateLoaded)
811 {
812 if(eState == OMX_StateIdle)
813 {
814 //if all buffers are allocated or all ports disabled
815 if(allocate_done() ||
816 ( m_sInPortDef.bEnabled == OMX_FALSE && m_sOutPortDef.bEnabled == OMX_FALSE))
817 {
818 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle\n");
819 }
820 else
821 {
822 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->Idle-Pending\n");
823 BITMASK_SET(&m_flags, OMX_COMPONENT_IDLE_PENDING);
824 // Skip the event notification
825 bFlag = 0;
826 }
827 }
828 /* Requesting transition from Loaded to Loaded */
829 else if(eState == OMX_StateLoaded)
830 {
831 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Loaded\n");
832 post_event(OMX_EventError,OMX_ErrorSameState,\
833 OMX_COMPONENT_GENERATE_EVENT);
834 eRet = OMX_ErrorSameState;
835 }
836 /* Requesting transition from Loaded to WaitForResources */
837 else if(eState == OMX_StateWaitForResources)
838 {
839 /* Since error is None , we will post an event
840 at the end of this function definition */
841 DEBUG_PRINT_LOW("OMXCORE-SM: Loaded-->WaitForResources\n");
842 }
843 /* Requesting transition from Loaded to Executing */
844 else if(eState == OMX_StateExecuting)
845 {
846 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Executing\n");
847 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
848 OMX_COMPONENT_GENERATE_EVENT);
849 eRet = OMX_ErrorIncorrectStateTransition;
850 }
851 /* Requesting transition from Loaded to Pause */
852 else if(eState == OMX_StatePause)
853 {
854 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Pause\n");
855 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
856 OMX_COMPONENT_GENERATE_EVENT);
857 eRet = OMX_ErrorIncorrectStateTransition;
858 }
859 /* Requesting transition from Loaded to Invalid */
860 else if(eState == OMX_StateInvalid)
861 {
862 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->Invalid\n");
863 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
864 eRet = OMX_ErrorInvalidState;
865 }
866 else
867 {
868 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Loaded-->%d Not Handled\n",\
869 eState);
870 eRet = OMX_ErrorBadParameter;
871 }
872 }
873
874 /***************************/
875 /* Current State is IDLE */
876 /***************************/
877 else if(m_state == OMX_StateIdle)
878 {
879 if(eState == OMX_StateLoaded)
880 {
881 if(release_done())
882 {
883 /*
884 Since error is None , we will post an event at the end
885 of this function definition
886 */
887 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded\n");
888 if(dev_stop() != 0)
889 {
890 DEBUG_PRINT_ERROR("\nERROR: dev_stop() failed at Idle --> Loaded");
891 eRet = OMX_ErrorHardware;
892 }
893 }
894 else
895 {
896 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Loaded-Pending\n");
897 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADING_PENDING);
898 // Skip the event notification
899 bFlag = 0;
900 }
901 }
902 /* Requesting transition from Idle to Executing */
903 else if(eState == OMX_StateExecuting)
904 {
905 if( dev_start() )
906 {
907 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Exe\n");
908 omx_report_error ();
909 eRet = OMX_ErrorHardware;
910 }
911 else
912 {
913 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
914 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Executing\n");
915 bFlag = 0;
916 }
917
918 dev_start_done();
919 }
920 /* Requesting transition from Idle to Idle */
921 else if(eState == OMX_StateIdle)
922 {
923 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Idle\n");
924 post_event(OMX_EventError,OMX_ErrorSameState,\
925 OMX_COMPONENT_GENERATE_EVENT);
926 eRet = OMX_ErrorSameState;
927 }
928 /* Requesting transition from Idle to WaitForResources */
929 else if(eState == OMX_StateWaitForResources)
930 {
931 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->WaitForResources\n");
932 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
933 OMX_COMPONENT_GENERATE_EVENT);
934 eRet = OMX_ErrorIncorrectStateTransition;
935 }
936 /* Requesting transition from Idle to Pause */
937 else if(eState == OMX_StatePause)
938 {
939 /*To pause the Video core we need to start the driver*/
940 if( dev_start() )
941 {
942 DEBUG_PRINT_ERROR("\nERROR: dev_start() failed in SCP on Idle --> Pause\n");
943 omx_report_error ();
944 eRet = OMX_ErrorHardware;
945 }
946 else
947 {
948 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
949 DEBUG_PRINT_LOW("OMXCORE-SM: Idle-->Pause\n");
950 bFlag = 0;
951 }
952 }
953 /* Requesting transition from Idle to Invalid */
954 else if(eState == OMX_StateInvalid)
955 {
956 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle-->Invalid\n");
957 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
958 eRet = OMX_ErrorInvalidState;
959 }
960 else
961 {
962 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Idle --> %d Not Handled\n",eState);
963 eRet = OMX_ErrorBadParameter;
964 }
965 }
966
967 /******************************/
968 /* Current State is Executing */
969 /******************************/
970 else if(m_state == OMX_StateExecuting)
971 {
972 /* Requesting transition from Executing to Idle */
973 if(eState == OMX_StateIdle)
974 {
975 /* Since error is None , we will post an event
976 at the end of this function definition
977 */
978 DEBUG_PRINT_LOW("\n OMXCORE-SM: Executing --> Idle \n");
979 //here this should be Pause-Idle pending and should be cleared when flush is complete and change the state to Idle
980 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
981 execute_omx_flush(OMX_ALL);
982 bFlag = 0;
983 dev_stop_done();
984 }
985 /* Requesting transition from Executing to Paused */
986 else if(eState == OMX_StatePause)
987 {
988
989 if(dev_pause())
990 {
991 DEBUG_PRINT_ERROR("\nERROR: dev_pause() failed in SCP on Exe --> Pause\n");
992 post_event(OMX_EventError,OMX_ErrorHardware,\
993 OMX_COMPONENT_GENERATE_EVENT);
994 eRet = OMX_ErrorHardware;
995 }
996 else
997 {
998 BITMASK_SET(&m_flags,OMX_COMPONENT_PAUSE_PENDING);
999 DEBUG_PRINT_LOW("OMXCORE-SM: Executing-->Pause\n");
1000 bFlag = 0;
1001 }
1002 }
1003 /* Requesting transition from Executing to Loaded */
1004 else if(eState == OMX_StateLoaded)
1005 {
1006 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Loaded \n");
1007 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1008 OMX_COMPONENT_GENERATE_EVENT);
1009 eRet = OMX_ErrorIncorrectStateTransition;
1010 }
1011 /* Requesting transition from Executing to WaitForResources */
1012 else if(eState == OMX_StateWaitForResources)
1013 {
1014 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> WaitForResources \n");
1015 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1016 OMX_COMPONENT_GENERATE_EVENT);
1017 eRet = OMX_ErrorIncorrectStateTransition;
1018 }
1019 /* Requesting transition from Executing to Executing */
1020 else if(eState == OMX_StateExecuting)
1021 {
1022 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Executing \n");
1023 post_event(OMX_EventError,OMX_ErrorSameState,\
1024 OMX_COMPONENT_GENERATE_EVENT);
1025 eRet = OMX_ErrorSameState;
1026 }
1027 /* Requesting transition from Executing to Invalid */
1028 else if(eState == OMX_StateInvalid)
1029 {
1030 DEBUG_PRINT_ERROR("\nERROR: OMXCORE-SM: Executing --> Invalid \n");
1031 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1032 eRet = OMX_ErrorInvalidState;
1033 }
1034 else
1035 {
1036 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Executing --> %d Not Handled\n",eState);
1037 eRet = OMX_ErrorBadParameter;
1038 }
1039 }
1040 /***************************/
1041 /* Current State is Pause */
1042 /***************************/
1043 else if(m_state == OMX_StatePause)
1044 {
1045 /* Requesting transition from Pause to Executing */
1046 if(eState == OMX_StateExecuting)
1047 {
1048 DEBUG_PRINT_LOW("\n Pause --> Executing \n");
1049 if( dev_resume() )
1050 {
1051 post_event(OMX_EventError,OMX_ErrorHardware,\
1052 OMX_COMPONENT_GENERATE_EVENT);
1053 eRet = OMX_ErrorHardware;
1054 }
1055 else
1056 {
1057 BITMASK_SET(&m_flags,OMX_COMPONENT_EXECUTE_PENDING);
1058 DEBUG_PRINT_LOW("OMXCORE-SM: Pause-->Executing\n");
1059 post_event (NULL, NULL, OMX_COMPONENT_GENERATE_RESUME_DONE);
1060 bFlag = 0;
1061 }
1062 }
1063 /* Requesting transition from Pause to Idle */
1064 else if(eState == OMX_StateIdle)
1065 {
1066 /* Since error is None , we will post an event
1067 at the end of this function definition */
1068 DEBUG_PRINT_LOW("\n Pause --> Idle \n");
1069 BITMASK_SET(&m_flags,OMX_COMPONENT_IDLE_PENDING);
1070 execute_omx_flush(OMX_ALL);
1071 bFlag = 0;
1072 }
1073 /* Requesting transition from Pause to loaded */
1074 else if(eState == OMX_StateLoaded)
1075 {
1076 DEBUG_PRINT_ERROR("\nERROR: Pause --> loaded \n");
1077 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1078 OMX_COMPONENT_GENERATE_EVENT);
1079 eRet = OMX_ErrorIncorrectStateTransition;
1080 }
1081 /* Requesting transition from Pause to WaitForResources */
1082 else if(eState == OMX_StateWaitForResources)
1083 {
1084 DEBUG_PRINT_ERROR("\nERROR: Pause --> WaitForResources \n");
1085 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1086 OMX_COMPONENT_GENERATE_EVENT);
1087 eRet = OMX_ErrorIncorrectStateTransition;
1088 }
1089 /* Requesting transition from Pause to Pause */
1090 else if(eState == OMX_StatePause)
1091 {
1092 DEBUG_PRINT_ERROR("\nERROR: Pause --> Pause \n");
1093 post_event(OMX_EventError,OMX_ErrorSameState,\
1094 OMX_COMPONENT_GENERATE_EVENT);
1095 eRet = OMX_ErrorSameState;
1096 }
1097 /* Requesting transition from Pause to Invalid */
1098 else if(eState == OMX_StateInvalid)
1099 {
1100 DEBUG_PRINT_ERROR("\nERROR: Pause --> Invalid \n");
1101 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1102 eRet = OMX_ErrorInvalidState;
1103 }
1104 else
1105 {
1106 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Paused --> %d Not Handled\n",eState);
1107 eRet = OMX_ErrorBadParameter;
1108 }
1109 }
1110 /***************************/
1111 /* Current State is WaitForResources */
1112 /***************************/
1113 else if(m_state == OMX_StateWaitForResources)
1114 {
1115 /* Requesting transition from WaitForResources to Loaded */
1116 if(eState == OMX_StateLoaded)
1117 {
1118 /* Since error is None , we will post an event
1119 at the end of this function definition */
1120 DEBUG_PRINT_LOW("OMXCORE-SM: WaitForResources-->Loaded\n");
1121 }
1122 /* Requesting transition from WaitForResources to WaitForResources */
1123 else if(eState == OMX_StateWaitForResources)
1124 {
1125 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->WaitForResources\n");
1126 post_event(OMX_EventError,OMX_ErrorSameState,
1127 OMX_COMPONENT_GENERATE_EVENT);
1128 eRet = OMX_ErrorSameState;
1129 }
1130 /* Requesting transition from WaitForResources to Executing */
1131 else if(eState == OMX_StateExecuting)
1132 {
1133 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Executing\n");
1134 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1135 OMX_COMPONENT_GENERATE_EVENT);
1136 eRet = OMX_ErrorIncorrectStateTransition;
1137 }
1138 /* Requesting transition from WaitForResources to Pause */
1139 else if(eState == OMX_StatePause)
1140 {
1141 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Pause\n");
1142 post_event(OMX_EventError,OMX_ErrorIncorrectStateTransition,\
1143 OMX_COMPONENT_GENERATE_EVENT);
1144 eRet = OMX_ErrorIncorrectStateTransition;
1145 }
1146 /* Requesting transition from WaitForResources to Invalid */
1147 else if(eState == OMX_StateInvalid)
1148 {
1149 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: WaitForResources-->Invalid\n");
1150 post_event(OMX_EventError,eState,OMX_COMPONENT_GENERATE_EVENT);
1151 eRet = OMX_ErrorInvalidState;
1152 }
1153 /* Requesting transition from WaitForResources to Loaded -
1154 is NOT tested by Khronos TS */
1155
1156 }
1157 else
1158 {
1159 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: %d --> %d(Not Handled)\n",m_state,eState);
1160 eRet = OMX_ErrorBadParameter;
1161 }
1162 }
1163 /********************************/
1164 /* Current State is Invalid */
1165 /*******************************/
1166 else if(m_state == OMX_StateInvalid)
1167 {
1168 /* State Transition from Inavlid to any state */
1169 if(eState == (OMX_StateLoaded || OMX_StateWaitForResources
1170 || OMX_StateIdle || OMX_StateExecuting
1171 || OMX_StatePause || OMX_StateInvalid))
1172 {
1173 DEBUG_PRINT_ERROR("ERROR: OMXCORE-SM: Invalid -->Loaded\n");
1174 post_event(OMX_EventError,OMX_ErrorInvalidState,\
1175 OMX_COMPONENT_GENERATE_EVENT);
1176 eRet = OMX_ErrorInvalidState;
1177 }
1178 }
1179 else if(cmd == OMX_CommandFlush)
1180 {
1181 if(0 == param1 || OMX_ALL == param1)
1182 {
1183 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_FLUSH_PENDING);
1184 }
1185 if(1 == param1 || OMX_ALL == param1)
1186 {
1187 //generate output flush event only.
1188 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_FLUSH_PENDING);
1189 }
1190
1191 execute_omx_flush(param1);
1192 bFlag = 0;
1193 }
1194 else if( cmd == OMX_CommandPortEnable)
1195 {
1196 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1197 {
1198 m_sInPortDef.bEnabled = OMX_TRUE;
1199
1200 if( (m_state == OMX_StateLoaded &&
1201 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1202 || allocate_input_done())
1203 {
1204 post_event(OMX_CommandPortEnable,PORT_INDEX_IN,
1205 OMX_COMPONENT_GENERATE_EVENT);
1206 }
1207 else
1208 {
1209 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1210 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_ENABLE_PENDING);
1211 // Skip the event notification
1212 bFlag = 0;
1213 }
1214 }
1215 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1216 {
1217 m_sOutPortDef.bEnabled = OMX_TRUE;
1218
1219 if( (m_state == OMX_StateLoaded &&
1220 !BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
1221 || (allocate_output_done()))
1222 {
1223 post_event(OMX_CommandPortEnable,PORT_INDEX_OUT,
1224 OMX_COMPONENT_GENERATE_EVENT);
1225
1226 }
1227 else
1228 {
1229 DEBUG_PRINT_LOW("OMXCORE-SM: Disabled-->Enabled Pending\n");
1230 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
1231 // Skip the event notification
1232 bFlag = 0;
1233 }
1234 }
1235 }
1236 else if(cmd == OMX_CommandPortDisable)
1237 {
1238 if(param1 == PORT_INDEX_IN || param1 == OMX_ALL)
1239 {
1240 m_sInPortDef.bEnabled = OMX_FALSE;
1241 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1242 && release_input_done())
1243 {
1244 post_event(OMX_CommandPortDisable,PORT_INDEX_IN,
1245 OMX_COMPONENT_GENERATE_EVENT);
1246 }
1247 else
1248 {
1249 BITMASK_SET(&m_flags, OMX_COMPONENT_INPUT_DISABLE_PENDING);
1250 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1251 {
1252 execute_omx_flush(PORT_INDEX_IN);
1253 }
1254
1255 // Skip the event notification
1256 bFlag = 0;
1257 }
1258 }
1259 if(param1 == PORT_INDEX_OUT || param1 == OMX_ALL)
1260 {
1261 m_sOutPortDef.bEnabled = OMX_FALSE;
1262
1263 if((m_state == OMX_StateLoaded || m_state == OMX_StateIdle)
1264 && release_output_done())
1265 {
1266 post_event(OMX_CommandPortDisable,PORT_INDEX_OUT,\
1267 OMX_COMPONENT_GENERATE_EVENT);
1268 }
1269 else
1270 {
1271 BITMASK_SET(&m_flags, OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
1272 if(m_state == OMX_StatePause ||m_state == OMX_StateExecuting)
1273 {
1274 execute_omx_flush(PORT_INDEX_OUT);
1275 }
1276 // Skip the event notification
1277 bFlag = 0;
1278
1279 }
1280 }
1281 }
1282 else
1283 {
1284 DEBUG_PRINT_ERROR("ERROR: Invalid Command received other than StateSet (%d)\n",cmd);
1285 eRet = OMX_ErrorNotImplemented;
1286 }
1287 if(eRet == OMX_ErrorNone && bFlag)
1288 {
1289 post_event(cmd,eState,OMX_COMPONENT_GENERATE_EVENT);
1290 }
1291 sem_post(&m_cmd_lock);
1292 return eRet;
1293 }
1294
1295 /* ======================================================================
1296 FUNCTION
1297 omx_venc::ExecuteOmxFlush
1298
1299 DESCRIPTION
1300 Executes the OMX flush.
1301
1302 PARAMETERS
1303 flushtype - input flush(1)/output flush(0)/ both.
1304
1305 RETURN VALUE
1306 true/false
1307
1308 ========================================================================== */
execute_omx_flush(OMX_U32 flushType)1309 bool omx_video::execute_omx_flush(OMX_U32 flushType)
1310 {
1311 bool bRet = false;
1312 DEBUG_PRINT_LOW("\n execute_omx_flush - %d\n", flushType);
1313 if(flushType == 0 || flushType == OMX_ALL)
1314 {
1315 input_flush_progress = true;
1316 //flush input only
1317 bRet = execute_input_flush();
1318 }
1319 if(flushType == 1 || flushType == OMX_ALL)
1320 {
1321 //flush output only
1322 output_flush_progress = true;
1323 bRet = execute_output_flush();
1324 }
1325 return bRet;
1326 }
1327 /*=========================================================================
1328 FUNCTION : execute_output_flush
1329
1330 DESCRIPTION
1331 Executes the OMX flush at OUTPUT PORT.
1332
1333 PARAMETERS
1334 None.
1335
1336 RETURN VALUE
1337 true/false
1338 ==========================================================================*/
execute_output_flush(void)1339 bool omx_video::execute_output_flush(void)
1340 {
1341 unsigned p1 = 0; // Parameter - 1
1342 unsigned p2 = 0; // Parameter - 2
1343 unsigned ident = 0;
1344 bool bRet = true;
1345
1346 /*Generate FBD for all Buffers in the FTBq*/
1347 DEBUG_PRINT_LOW("\n execute_output_flush\n");
1348 pthread_mutex_lock(&m_lock);
1349 while(m_ftb_q.m_size)
1350 {
1351 m_ftb_q.pop_entry(&p1,&p2,&ident);
1352
1353 if(ident == OMX_COMPONENT_GENERATE_FTB )
1354 {
1355 pending_output_buffers++;
1356 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1357 }
1358 else if(ident == OMX_COMPONENT_GENERATE_FBD)
1359 {
1360 fill_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1361 }
1362 }
1363
1364 pthread_mutex_unlock(&m_lock);
1365 /*Check if there are buffers with the Driver*/
1366 if(dev_flush(PORT_INDEX_OUT))
1367 {
1368 DEBUG_PRINT_ERROR("\nERROR: o/p dev_flush() Failed");
1369 return false;
1370 }
1371
1372 return bRet;
1373 }
1374 /*=========================================================================
1375 FUNCTION : execute_input_flush
1376
1377 DESCRIPTION
1378 Executes the OMX flush at INPUT PORT.
1379
1380 PARAMETERS
1381 None.
1382
1383 RETURN VALUE
1384 true/false
1385 ==========================================================================*/
execute_input_flush(void)1386 bool omx_video::execute_input_flush(void)
1387 {
1388 unsigned p1 = 0; // Parameter - 1
1389 unsigned p2 = 0; // Parameter - 2
1390 unsigned ident = 0;
1391 bool bRet = true;
1392
1393 /*Generate EBD for all Buffers in the ETBq*/
1394 DEBUG_PRINT_LOW("\n execute_input_flush\n");
1395
1396 pthread_mutex_lock(&m_lock);
1397 while(m_etb_q.m_size)
1398 {
1399 m_etb_q.pop_entry(&p1,&p2,&ident);
1400 if(ident == OMX_COMPONENT_GENERATE_ETB)
1401 {
1402 pending_input_buffers++;
1403 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p2);
1404 }
1405 else if(ident == OMX_COMPONENT_GENERATE_EBD)
1406 {
1407 empty_buffer_done(&m_cmp,(OMX_BUFFERHEADERTYPE *)p1);
1408 }
1409 else if(ident == OMX_COMPONENT_GENERATE_ETB_OPQ)
1410 {
1411 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,(OMX_BUFFERHEADERTYPE *)p2);
1412 }
1413 }
1414 if(mUseProxyColorFormat) {
1415 if(psource_frame) {
1416 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,psource_frame);
1417 psource_frame = NULL;
1418 }
1419 while(m_opq_meta_q.m_size) {
1420 unsigned p1,p2,id;
1421 m_opq_meta_q.pop_entry(&p1,&p2,&id);
1422 m_pCallbacks.EmptyBufferDone(&m_cmp,m_app_data,
1423 (OMX_BUFFERHEADERTYPE *)p1);
1424 }
1425 if(pdest_frame){
1426 m_opq_pmem_q.insert_entry((unsigned int)pdest_frame,0,0);
1427 pdest_frame = NULL;
1428 }
1429 }
1430 pthread_mutex_unlock(&m_lock);
1431 /*Check if there are buffers with the Driver*/
1432 if(dev_flush(PORT_INDEX_IN))
1433 {
1434 DEBUG_PRINT_ERROR("\nERROR: i/p dev_flush() Failed");
1435 return false;
1436 }
1437
1438 return bRet;
1439 }
1440
1441
1442 /* ======================================================================
1443 FUNCTION
1444 omx_venc::SendCommandEvent
1445
1446 DESCRIPTION
1447 Send the event to decoder pipe. This is needed to generate the callbacks
1448 in decoder thread context.
1449
1450 PARAMETERS
1451 None.
1452
1453 RETURN VALUE
1454 true/false
1455
1456 ========================================================================== */
post_event(unsigned int p1,unsigned int p2,unsigned int id)1457 bool omx_video::post_event(unsigned int p1,
1458 unsigned int p2,
1459 unsigned int id)
1460 {
1461 bool bRet = false;
1462
1463
1464 pthread_mutex_lock(&m_lock);
1465
1466 if( id == OMX_COMPONENT_GENERATE_FTB || \
1467 (id == OMX_COMPONENT_GENERATE_FRAME_DONE))
1468 {
1469 m_ftb_q.insert_entry(p1,p2,id);
1470 }
1471 else if((id == m_input_msg_id) \
1472 || (id == OMX_COMPONENT_GENERATE_EBD))
1473 {
1474 m_etb_q.insert_entry(p1,p2,id);
1475 }
1476 else
1477 {
1478 m_cmd_q.insert_entry(p1,p2,id);
1479 }
1480
1481 bRet = true;
1482 DEBUG_PRINT_LOW("\n Value of this pointer in post_event %p",this);
1483 post_message(this, id);
1484 pthread_mutex_unlock(&m_lock);
1485
1486 return bRet;
1487 }
1488
1489 /* ======================================================================
1490 FUNCTION
1491 omx_venc::GetParameter
1492
1493 DESCRIPTION
1494 OMX Get Parameter method implementation
1495
1496 PARAMETERS
1497 <TBD>.
1498
1499 RETURN VALUE
1500 Error None if successful.
1501
1502 ========================================================================== */
get_parameter(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE paramIndex,OMX_INOUT OMX_PTR paramData)1503 OMX_ERRORTYPE omx_video::get_parameter(OMX_IN OMX_HANDLETYPE hComp,
1504 OMX_IN OMX_INDEXTYPE paramIndex,
1505 OMX_INOUT OMX_PTR paramData)
1506 {
1507 OMX_ERRORTYPE eRet = OMX_ErrorNone;
1508 unsigned int height=0,width = 0;
1509
1510 DEBUG_PRINT_LOW("get_parameter: \n");
1511 if(m_state == OMX_StateInvalid)
1512 {
1513 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid State\n");
1514 return OMX_ErrorInvalidState;
1515 }
1516 if(paramData == NULL)
1517 {
1518 DEBUG_PRINT_ERROR("ERROR: Get Param in Invalid paramData \n");
1519 return OMX_ErrorBadParameter;
1520 }
1521 switch(paramIndex)
1522 {
1523 case OMX_IndexParamPortDefinition:
1524 {
1525 OMX_PARAM_PORTDEFINITIONTYPE *portDefn;
1526 portDefn = (OMX_PARAM_PORTDEFINITIONTYPE *) paramData;
1527
1528 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPortDefinition\n");
1529 if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1530 {
1531 DEBUG_PRINT_LOW("m_sInPortDef: size = %d, min cnt = %d, actual cnt = %d",
1532 m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountMin,
1533 m_sInPortDef.nBufferCountActual);
1534 memcpy(portDefn, &m_sInPortDef, sizeof(m_sInPortDef));
1535 #ifdef _ANDROID_ICS_
1536 if(meta_mode_enable)
1537 {
1538 portDefn->nBufferSize = sizeof(encoder_media_buffer_type);
1539 }
1540 if(secure_session) {
1541 portDefn->format.video.eColorFormat =
1542 (OMX_COLOR_FORMATTYPE)secure_color_format;
1543 }
1544 else if (mUseProxyColorFormat) {
1545 portDefn->format.video.eColorFormat =
1546 (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1547 }
1548 #endif
1549 }
1550 else if(portDefn->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1551 {
1552 dev_get_buf_req (&m_sOutPortDef.nBufferCountMin,
1553 &m_sOutPortDef.nBufferCountActual,
1554 &m_sOutPortDef.nBufferSize,
1555 m_sOutPortDef.nPortIndex);
1556 DEBUG_PRINT_LOW("m_sOutPortDef: size = %d, min cnt = %d, actual cnt = %d",
1557 m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountMin,
1558 m_sOutPortDef.nBufferCountActual);
1559 memcpy(portDefn, &m_sOutPortDef, sizeof(m_sOutPortDef));
1560 }
1561 else
1562 {
1563 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1564 eRet = OMX_ErrorBadPortIndex;
1565 }
1566 break;
1567 }
1568 case OMX_IndexParamVideoInit:
1569 {
1570 OMX_PORT_PARAM_TYPE *portParamType =
1571 (OMX_PORT_PARAM_TYPE *) paramData;
1572 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoInit\n");
1573
1574 memcpy(portParamType, &m_sPortParam, sizeof(m_sPortParam));
1575 break;
1576 }
1577 case OMX_IndexParamVideoPortFormat:
1578 {
1579 OMX_VIDEO_PARAM_PORTFORMATTYPE *portFmt =
1580 (OMX_VIDEO_PARAM_PORTFORMATTYPE *)paramData;
1581 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoPortFormat\n");
1582
1583 if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_IN)
1584 {
1585 int index = portFmt->nIndex;
1586
1587 if (index > 1) {
1588 eRet = OMX_ErrorNoMore;
1589 } else {
1590 memcpy(portFmt, &m_sInPortFormat, sizeof(m_sInPortFormat));
1591 #ifdef _ANDROID_ICS_
1592 if (index == 1) {
1593 //we support two formats
1594 //index 0 - YUV420SP
1595 //index 1 - opaque which internally maps to YUV420SP.
1596 //this can be extended in the future
1597 portFmt->nIndex = index; //restore index set from client
1598 portFmt->eColorFormat =
1599 (OMX_COLOR_FORMATTYPE)QOMX_COLOR_FormatAndroidOpaque;
1600 }
1601 }
1602 #endif
1603 }
1604 else if(portFmt->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1605 {
1606 memcpy(portFmt, &m_sOutPortFormat, sizeof(m_sOutPortFormat));
1607 }
1608 else
1609 {
1610 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1611 eRet = OMX_ErrorBadPortIndex;
1612 }
1613 break;
1614 }
1615 case OMX_IndexParamVideoBitrate:
1616 {
1617 OMX_VIDEO_PARAM_BITRATETYPE* pParam = (OMX_VIDEO_PARAM_BITRATETYPE*)paramData;
1618 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoBitrate\n");
1619
1620 if(pParam->nPortIndex == (OMX_U32) PORT_INDEX_OUT)
1621 {
1622 memcpy(pParam, &m_sParamBitrate, sizeof(m_sParamBitrate));
1623 }
1624 else
1625 {
1626 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1627 eRet = OMX_ErrorBadPortIndex;
1628 }
1629
1630 break;
1631 }
1632 case OMX_IndexParamVideoMpeg4:
1633 {
1634 OMX_VIDEO_PARAM_MPEG4TYPE* pParam = (OMX_VIDEO_PARAM_MPEG4TYPE*)paramData;
1635 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoMpeg4\n");
1636 memcpy(pParam, &m_sParamMPEG4, sizeof(m_sParamMPEG4));
1637 break;
1638 }
1639 case OMX_IndexParamVideoH263:
1640 {
1641 OMX_VIDEO_PARAM_H263TYPE* pParam = (OMX_VIDEO_PARAM_H263TYPE*)paramData;
1642 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoH263\n");
1643 memcpy(pParam, &m_sParamH263, sizeof(m_sParamH263));
1644 break;
1645 }
1646 case OMX_IndexParamVideoAvc:
1647 {
1648 OMX_VIDEO_PARAM_AVCTYPE* pParam = (OMX_VIDEO_PARAM_AVCTYPE*)paramData;
1649 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoAvc\n");
1650 memcpy(pParam, &m_sParamAVC, sizeof(m_sParamAVC));
1651 break;
1652 }
1653 case OMX_IndexParamVideoProfileLevelQuerySupported:
1654 {
1655 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1656 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported\n");
1657 eRet = get_supported_profile_level(pParam);
1658 if(eRet)
1659 DEBUG_PRINT_ERROR("Invalid entry returned from get_supported_profile_level %d, %d",
1660 pParam->eProfile, pParam->eLevel);
1661 break;
1662 }
1663 case OMX_IndexParamVideoProfileLevelCurrent:
1664 {
1665 OMX_VIDEO_PARAM_PROFILELEVELTYPE* pParam = (OMX_VIDEO_PARAM_PROFILELEVELTYPE*)paramData;
1666 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelCurrent\n");
1667 memcpy(pParam, &m_sParamProfileLevel, sizeof(m_sParamProfileLevel));
1668 break;
1669 }
1670 /*Component should support this port definition*/
1671 case OMX_IndexParamAudioInit:
1672 {
1673 OMX_PORT_PARAM_TYPE *audioPortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1674 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamAudioInit\n");
1675 memcpy(audioPortParamType, &m_sPortParam_audio, sizeof(m_sPortParam_audio));
1676 break;
1677 }
1678 /*Component should support this port definition*/
1679 case OMX_IndexParamImageInit:
1680 {
1681 OMX_PORT_PARAM_TYPE *imagePortParamType = (OMX_PORT_PARAM_TYPE *) paramData;
1682 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamImageInit\n");
1683 memcpy(imagePortParamType, &m_sPortParam_img, sizeof(m_sPortParam_img));
1684 break;
1685
1686 }
1687 /*Component should support this port definition*/
1688 case OMX_IndexParamOtherInit:
1689 {
1690 DEBUG_PRINT_ERROR("ERROR: get_parameter: OMX_IndexParamOtherInit %08x\n", paramIndex);
1691 eRet =OMX_ErrorUnsupportedIndex;
1692 break;
1693 }
1694 case OMX_IndexParamStandardComponentRole:
1695 {
1696 OMX_PARAM_COMPONENTROLETYPE *comp_role;
1697 comp_role = (OMX_PARAM_COMPONENTROLETYPE *) paramData;
1698 comp_role->nVersion.nVersion = OMX_SPEC_VERSION;
1699 comp_role->nSize = sizeof(*comp_role);
1700
1701 DEBUG_PRINT_LOW("Getparameter: OMX_IndexParamStandardComponentRole %d\n",paramIndex);
1702 strlcpy((char*)comp_role->cRole,(const char*)m_cRole,OMX_MAX_STRINGNAME_SIZE);
1703 break;
1704 }
1705 /* Added for parameter test */
1706 case OMX_IndexParamPriorityMgmt:
1707 {
1708
1709 OMX_PRIORITYMGMTTYPE *priorityMgmType = (OMX_PRIORITYMGMTTYPE *) paramData;
1710 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamPriorityMgmt\n");
1711 memcpy(priorityMgmType, &m_sPriorityMgmt, sizeof(m_sPriorityMgmt));
1712 break;
1713 }
1714 /* Added for parameter test */
1715 case OMX_IndexParamCompBufferSupplier:
1716 {
1717 OMX_PARAM_BUFFERSUPPLIERTYPE *bufferSupplierType = (OMX_PARAM_BUFFERSUPPLIERTYPE*) paramData;
1718 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamCompBufferSupplier\n");
1719 if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_IN)
1720 {
1721 memcpy(bufferSupplierType, &m_sInBufSupplier, sizeof(m_sInBufSupplier));
1722 }
1723 else if(bufferSupplierType->nPortIndex ==(OMX_U32) PORT_INDEX_OUT)
1724 {
1725 memcpy(bufferSupplierType, &m_sOutBufSupplier, sizeof(m_sOutBufSupplier));
1726 }
1727 else
1728 {
1729 DEBUG_PRINT_ERROR("ERROR: GetParameter called on Bad Port Index");
1730 eRet = OMX_ErrorBadPortIndex;
1731 }
1732 break;
1733 }
1734
1735 case OMX_IndexParamVideoQuantization:
1736 {
1737 OMX_VIDEO_PARAM_QUANTIZATIONTYPE *session_qp = (OMX_VIDEO_PARAM_QUANTIZATIONTYPE*) paramData;
1738 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoQuantization\n");
1739 memcpy(session_qp, &m_sSessionQuantization, sizeof(m_sSessionQuantization));
1740 break;
1741 }
1742
1743 case OMX_IndexParamVideoErrorCorrection:
1744 {
1745 OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE* errorresilience = (OMX_VIDEO_PARAM_ERRORCORRECTIONTYPE*)paramData;
1746 DEBUG_PRINT_LOW("OMX_IndexParamVideoErrorCorrection\n");
1747 errorresilience->bEnableHEC = m_sErrorCorrection.bEnableHEC;
1748 errorresilience->bEnableResync = m_sErrorCorrection.bEnableResync;
1749 errorresilience->nResynchMarkerSpacing = m_sErrorCorrection.nResynchMarkerSpacing;
1750 break;
1751 }
1752 case OMX_IndexParamVideoIntraRefresh:
1753 {
1754 OMX_VIDEO_PARAM_INTRAREFRESHTYPE* intrarefresh = (OMX_VIDEO_PARAM_INTRAREFRESHTYPE*)paramData;
1755 DEBUG_PRINT_LOW("OMX_IndexParamVideoIntraRefresh\n");
1756 DEBUG_PRINT_ERROR("OMX_IndexParamVideoIntraRefresh GET\n");
1757 intrarefresh->eRefreshMode = m_sIntraRefresh.eRefreshMode;
1758 intrarefresh->nCirMBs = m_sIntraRefresh.nCirMBs;
1759 break;
1760 }
1761 case OMX_QcomIndexPortDefn:
1762 //TODO
1763 break;
1764 case OMX_COMPONENT_CAPABILITY_TYPE_INDEX:
1765 {
1766 OMXComponentCapabilityFlagsType *pParam = reinterpret_cast<OMXComponentCapabilityFlagsType*>(paramData);
1767 DEBUG_PRINT_LOW("get_parameter: OMX_COMPONENT_CAPABILITY_TYPE_INDEX\n");
1768 pParam->iIsOMXComponentMultiThreaded = OMX_TRUE;
1769 pParam->iOMXComponentSupportsExternalOutputBufferAlloc = OMX_FALSE;
1770 pParam->iOMXComponentSupportsExternalInputBufferAlloc = OMX_TRUE;
1771 pParam->iOMXComponentSupportsMovableInputBuffers = OMX_TRUE;
1772 pParam->iOMXComponentUsesNALStartCodes = OMX_TRUE;
1773 pParam->iOMXComponentSupportsPartialFrames = OMX_FALSE;
1774 pParam->iOMXComponentCanHandleIncompleteFrames = OMX_FALSE;
1775 pParam->iOMXComponentUsesFullAVCFrames = OMX_FALSE;
1776 m_use_input_pmem = OMX_TRUE;
1777 DEBUG_PRINT_LOW("Supporting capability index in encoder node");
1778 break;
1779 }
1780 #ifndef MAX_RES_720P
1781 case OMX_QcomIndexParamIndexExtraDataType:
1782 {
1783 DEBUG_PRINT_LOW("get_parameter: OMX_QcomIndexParamIndexExtraDataType");
1784 QOMX_INDEXEXTRADATATYPE *pParam = (QOMX_INDEXEXTRADATATYPE *)paramData;
1785 if (pParam->nIndex == (OMX_INDEXTYPE)OMX_ExtraDataVideoEncoderSliceInfo)
1786 {
1787 if (pParam->nPortIndex == PORT_INDEX_OUT)
1788 {
1789 pParam->bEnabled =
1790 (OMX_BOOL)((m_sExtraData & VEN_EXTRADATA_SLICEINFO) ? 1 : 0);
1791 DEBUG_PRINT_HIGH("Slice Info extradata %d", pParam->bEnabled);
1792 }
1793 else
1794 {
1795 DEBUG_PRINT_ERROR("get_parameter: slice information is "
1796 "valid for output port only");
1797 eRet =OMX_ErrorUnsupportedIndex;
1798 }
1799 }
1800 else
1801 {
1802 DEBUG_PRINT_ERROR("get_parameter: unsupported index (%x), "
1803 "only slice information extradata is supported", pParam->nIndex);
1804 eRet =OMX_ErrorUnsupportedIndex;
1805 }
1806 break;
1807 }
1808 #endif
1809 case QOMX_IndexParamVideoSyntaxHdr:
1810 {
1811 DEBUG_PRINT_HIGH("QOMX_IndexParamVideoSyntaxHdr");
1812 QOMX_EXTNINDEX_PARAMTYPE* pParam =
1813 reinterpret_cast<QOMX_EXTNINDEX_PARAMTYPE*>(paramData);
1814 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1815 if(dev_loaded_start())
1816 {
1817 DEBUG_PRINT_LOW("device start successful");
1818 }
1819 else
1820 {
1821 DEBUG_PRINT_ERROR("device start failed");
1822 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_START_PENDING);
1823 return OMX_ErrorHardware;
1824 }
1825 if(dev_get_seq_hdr(pParam->pData,
1826 (unsigned)(pParam->nSize - sizeof(QOMX_EXTNINDEX_PARAMTYPE)),
1827 (unsigned *)&pParam->nDataSize))
1828 {
1829 DEBUG_PRINT_HIGH("get syntax header successful (hdrlen = %d)",
1830 pParam->nDataSize);
1831 for (unsigned i = 0; i < pParam->nDataSize; i++) {
1832 DEBUG_PRINT_LOW("Header[%d] = %x", i, *((char *)pParam->pData + i));
1833 }
1834 }
1835 else
1836 {
1837 DEBUG_PRINT_ERROR("Error returned from GetSyntaxHeader()");
1838 eRet = OMX_ErrorHardware;
1839 }
1840 BITMASK_SET(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1841 if(dev_loaded_stop())
1842 {
1843 DEBUG_PRINT_LOW("device stop successful");
1844 }
1845 else
1846 {
1847 DEBUG_PRINT_ERROR("device stop failed");
1848 BITMASK_CLEAR(&m_flags, OMX_COMPONENT_LOADED_STOP_PENDING);
1849 eRet = OMX_ErrorHardware;
1850 }
1851 break;
1852 }
1853 case OMX_IndexParamVideoSliceFMO:
1854 default:
1855 {
1856 DEBUG_PRINT_ERROR("ERROR: get_parameter: unknown param %08x\n", paramIndex);
1857 eRet =OMX_ErrorUnsupportedIndex;
1858 break;
1859 }
1860
1861 }
1862
1863 return eRet;
1864
1865 }
1866 /* ======================================================================
1867 FUNCTION
1868 omx_video::GetConfig
1869
1870 DESCRIPTION
1871 OMX Get Config Method implementation.
1872
1873 PARAMETERS
1874 <TBD>.
1875
1876 RETURN VALUE
1877 OMX Error None if successful.
1878
1879 ========================================================================== */
get_config(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_INDEXTYPE configIndex,OMX_INOUT OMX_PTR configData)1880 OMX_ERRORTYPE omx_video::get_config(OMX_IN OMX_HANDLETYPE hComp,
1881 OMX_IN OMX_INDEXTYPE configIndex,
1882 OMX_INOUT OMX_PTR configData)
1883 {
1884 ////////////////////////////////////////////////////////////////
1885 // Supported Config Index Type
1886 // =============================================================
1887 // OMX_IndexConfigVideoBitrate OMX_VIDEO_CONFIG_BITRATETYPE
1888 // OMX_IndexConfigVideoFramerate OMX_CONFIG_FRAMERATETYPE
1889 // OMX_IndexConfigCommonRotate OMX_CONFIG_ROTATIONTYPE
1890 ////////////////////////////////////////////////////////////////
1891
1892 if(configData == NULL)
1893 {
1894 DEBUG_PRINT_ERROR("ERROR: param is null");
1895 return OMX_ErrorBadParameter;
1896 }
1897
1898 if(m_state == OMX_StateInvalid)
1899 {
1900 DEBUG_PRINT_ERROR("ERROR: can't be in invalid state");
1901 return OMX_ErrorIncorrectStateOperation;
1902 }
1903
1904 //@todo need to validate params
1905 switch(configIndex)
1906 {
1907 case OMX_IndexConfigVideoBitrate:
1908 {
1909 OMX_VIDEO_CONFIG_BITRATETYPE* pParam = reinterpret_cast<OMX_VIDEO_CONFIG_BITRATETYPE*>(configData);
1910 memcpy(pParam, &m_sConfigBitrate, sizeof(m_sConfigBitrate));
1911 break;
1912 }
1913 case OMX_IndexConfigVideoFramerate:
1914 {
1915 OMX_CONFIG_FRAMERATETYPE* pParam = reinterpret_cast<OMX_CONFIG_FRAMERATETYPE*>(configData);
1916 memcpy(pParam, &m_sConfigFramerate, sizeof(m_sConfigFramerate));
1917 break;
1918 }
1919 case OMX_IndexConfigCommonRotate:
1920 {
1921 OMX_CONFIG_ROTATIONTYPE* pParam = reinterpret_cast<OMX_CONFIG_ROTATIONTYPE*>(configData);
1922 memcpy(pParam, &m_sConfigFrameRotation, sizeof(m_sConfigFrameRotation));
1923 break;
1924 }
1925 case QOMX_IndexConfigVideoIntraperiod:
1926 {
1927 DEBUG_PRINT_LOW("get_config:QOMX_IndexConfigVideoIntraperiod\n");
1928 QOMX_VIDEO_INTRAPERIODTYPE* pParam = reinterpret_cast<QOMX_VIDEO_INTRAPERIODTYPE*>(configData);
1929 memcpy(pParam, &m_sIntraperiod, sizeof(m_sIntraperiod));
1930 break;
1931 }
1932 default:
1933 DEBUG_PRINT_ERROR("ERROR: unsupported index %d", (int) configIndex);
1934 return OMX_ErrorUnsupportedIndex;
1935 }
1936 return OMX_ErrorNone;
1937
1938 }
1939
1940 /* ======================================================================
1941 FUNCTION
1942 omx_video::GetExtensionIndex
1943
1944 DESCRIPTION
1945 OMX GetExtensionIndex method implementaion. <TBD>
1946
1947 PARAMETERS
1948 <TBD>.
1949
1950 RETURN VALUE
1951 OMX Error None if everything successful.
1952
1953 ========================================================================== */
get_extension_index(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_STRING paramName,OMX_OUT OMX_INDEXTYPE * indexType)1954 OMX_ERRORTYPE omx_video::get_extension_index(OMX_IN OMX_HANDLETYPE hComp,
1955 OMX_IN OMX_STRING paramName,
1956 OMX_OUT OMX_INDEXTYPE* indexType)
1957 {
1958 char *extns[] = {
1959 "OMX.QCOM.index.param.SliceDeliveryMode",
1960 "OMX.google.android.index.storeMetaDataInBuffers",
1961 "OMX.google.android.index.prependSPSPPSToIDRFrames",
1962 "OMX.google.android.index.setVUIStreamRestrictFlag"
1963 };
1964
1965 if(m_state == OMX_StateInvalid)
1966 {
1967 DEBUG_PRINT_ERROR("ERROR: Get Extension Index in Invalid State\n");
1968 return OMX_ErrorInvalidState;
1969 }
1970 #ifdef MAX_RES_1080P
1971 if (!strncmp(paramName, extns[0], strlen(extns[0]))) {
1972 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexEnableSliceDeliveryMode;
1973 return OMX_ErrorNone;
1974 }
1975 #endif
1976 #ifdef _ANDROID_ICS_
1977 if (!strncmp(paramName, extns[1], strlen(extns[1]))) {
1978 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamVideoMetaBufferMode;
1979 return OMX_ErrorNone;
1980 } else if (!strncmp(paramName, extns[2], strlen(extns[2]))) {
1981 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamSequenceHeaderWithIDR;
1982 return OMX_ErrorNone;
1983 } else if (!strncmp(paramName, extns[3], strlen(extns[3]))) {
1984 *indexType = (OMX_INDEXTYPE)OMX_QcomIndexParamEnableVUIStreamRestrictFlag;
1985 return OMX_ErrorNone;
1986 }
1987 #endif
1988 return OMX_ErrorNotImplemented;
1989 }
1990
1991 /* ======================================================================
1992 FUNCTION
1993 omx_video::GetState
1994
1995 DESCRIPTION
1996 Returns the state information back to the caller.<TBD>
1997
1998 PARAMETERS
1999 <TBD>.
2000
2001 RETURN VALUE
2002 Error None if everything is successful.
2003 ========================================================================== */
get_state(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_STATETYPE * state)2004 OMX_ERRORTYPE omx_video::get_state(OMX_IN OMX_HANDLETYPE hComp,
2005 OMX_OUT OMX_STATETYPE* state)
2006 {
2007 *state = m_state;
2008 DEBUG_PRINT_LOW("get_state: Returning the state %d\n",*state);
2009 return OMX_ErrorNone;
2010 }
2011
2012 /* ======================================================================
2013 FUNCTION
2014 omx_video::ComponentTunnelRequest
2015
2016 DESCRIPTION
2017 OMX Component Tunnel Request method implementation. <TBD>
2018
2019 PARAMETERS
2020 None.
2021
2022 RETURN VALUE
2023 OMX Error None if everything successful.
2024
2025 ========================================================================== */
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)2026 OMX_ERRORTYPE omx_video::component_tunnel_request(OMX_IN OMX_HANDLETYPE hComp,
2027 OMX_IN OMX_U32 port,
2028 OMX_IN OMX_HANDLETYPE peerComponent,
2029 OMX_IN OMX_U32 peerPort,
2030 OMX_INOUT OMX_TUNNELSETUPTYPE* tunnelSetup)
2031 {
2032 DEBUG_PRINT_ERROR("ERROR: component_tunnel_request Not Implemented\n");
2033 return OMX_ErrorNotImplemented;
2034 }
2035
2036 /* ======================================================================
2037 FUNCTION
2038 omx_video::UseInputBuffer
2039
2040 DESCRIPTION
2041 Helper function for Use buffer in the input pin
2042
2043 PARAMETERS
2044 None.
2045
2046 RETURN VALUE
2047 true/false
2048
2049 ========================================================================== */
use_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,OMX_IN OMX_U8 * buffer)2050 OMX_ERRORTYPE omx_video::use_input_buffer(
2051 OMX_IN OMX_HANDLETYPE hComp,
2052 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2053 OMX_IN OMX_U32 port,
2054 OMX_IN OMX_PTR appData,
2055 OMX_IN OMX_U32 bytes,
2056 OMX_IN OMX_U8* buffer)
2057 {
2058 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2059
2060 unsigned i = 0;
2061 unsigned char *buf_addr = NULL;
2062
2063 DEBUG_PRINT_HIGH("use_input_buffer: port = %d appData = %p bytes = %d buffer = %p",port,appData,bytes,buffer);
2064 if(bytes != m_sInPortDef.nBufferSize || secure_session)
2065 {
2066 DEBUG_PRINT_ERROR("\nERROR: use_input_buffer: Size Mismatch!! "
2067 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sInPortDef.nBufferSize);
2068 return OMX_ErrorBadParameter;
2069 }
2070
2071 if(!m_inp_mem_ptr)
2072 {
2073 input_use_buffer = true;
2074 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
2075 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
2076 if(m_inp_mem_ptr == NULL)
2077 {
2078 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
2079 return OMX_ErrorInsufficientResources;
2080 }
2081
2082
2083 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
2084 if(m_pInput_pmem == NULL)
2085 {
2086 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
2087 return OMX_ErrorInsufficientResources;
2088 }
2089 #ifdef USE_ION
2090 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
2091 if(m_pInput_ion == NULL)
2092 {
2093 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
2094 return OMX_ErrorInsufficientResources;
2095 }
2096 #endif
2097
2098 for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2099 {
2100 m_pInput_pmem[i].fd = -1;
2101 #ifdef USE_ION
2102 m_pInput_ion[i].ion_device_fd =-1;
2103 m_pInput_ion[i].fd_ion_data.fd =-1;
2104 m_pInput_ion[i].ion_alloc_data.handle=NULL;
2105 #endif
2106 }
2107
2108 }
2109
2110 for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2111 {
2112 if(BITMASK_ABSENT(&m_inp_bm_count,i))
2113 {
2114 break;
2115 }
2116 }
2117
2118 if(i < m_sInPortDef.nBufferCountActual)
2119 {
2120
2121 *bufferHdr = (m_inp_mem_ptr + i);
2122 BITMASK_SET(&m_inp_bm_count,i);
2123
2124 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
2125 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2126 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
2127 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
2128 (*bufferHdr)->pAppPrivate = appData;
2129 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
2130
2131 if(!m_use_input_pmem)
2132 {
2133 #ifdef USE_ION
2134 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
2135 &m_pInput_ion[i].ion_alloc_data,
2136 &m_pInput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2137 if(m_pInput_ion[i].ion_device_fd < 0) {
2138 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2139 return OMX_ErrorInsufficientResources;
2140 }
2141 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
2142 #else
2143 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2144 if(m_pInput_pmem[i].fd == 0)
2145 {
2146 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2147 }
2148
2149 if(m_pInput_pmem[i] .fd < 0)
2150 {
2151 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
2152 return OMX_ErrorInsufficientResources;
2153 }
2154 #endif
2155 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2156 m_pInput_pmem[i].offset = 0;
2157 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
2158 MAP_SHARED,m_pInput_pmem[i].fd,0);
2159
2160 if(m_pInput_pmem[i].buffer == MAP_FAILED)
2161 {
2162 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
2163 close(m_pInput_pmem[i].fd);
2164 #ifdef USE_ION
2165 free_ion_memory(&m_pInput_ion[i]);
2166 #endif
2167 return OMX_ErrorInsufficientResources;
2168 }
2169 }
2170 else
2171 {
2172 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *>((*bufferHdr)->pAppPrivate);
2173 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
2174
2175 if(pParam)
2176 {
2177 m_pInput_pmem[i].fd = pParam->pmem_fd;
2178 m_pInput_pmem[i].offset = pParam->offset;
2179 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2180 m_pInput_pmem[i].buffer = (unsigned char *)buffer;
2181 DEBUG_PRINT_LOW("\n DBG:: pParam->pmem_fd = %u, pParam->offset = %u",
2182 pParam->pmem_fd, pParam->offset);
2183 }
2184 else
2185 {
2186 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM i/p UseBuffer case");
2187 return OMX_ErrorBadParameter;
2188 }
2189 }
2190
2191 DEBUG_PRINT_LOW("\nuse_inp:: bufhdr = %p, pBuffer = %p, m_pInput_pmem[i].buffer = %p",
2192 (*bufferHdr), (*bufferHdr)->pBuffer, m_pInput_pmem[i].buffer);
2193 if( dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true)
2194 {
2195 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf() Failed for i/p buf");
2196 return OMX_ErrorInsufficientResources;
2197 }
2198 }
2199 else
2200 {
2201 DEBUG_PRINT_ERROR("\nERROR: All buffers are already used, invalid use_buf call for "
2202 "index = %u", i);
2203 eRet = OMX_ErrorInsufficientResources;
2204 }
2205
2206 return eRet;
2207 }
2208
2209
2210
2211 /* ======================================================================
2212 FUNCTION
2213 omx_video::UseOutputBuffer
2214
2215 DESCRIPTION
2216 Helper function for Use buffer in the input pin
2217
2218 PARAMETERS
2219 None.
2220
2221 RETURN VALUE
2222 true/false
2223
2224 ========================================================================== */
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)2225 OMX_ERRORTYPE omx_video::use_output_buffer(
2226 OMX_IN OMX_HANDLETYPE hComp,
2227 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2228 OMX_IN OMX_U32 port,
2229 OMX_IN OMX_PTR appData,
2230 OMX_IN OMX_U32 bytes,
2231 OMX_IN OMX_U8* buffer)
2232 {
2233 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2234 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
2235 unsigned i= 0; // Temporary counter
2236 unsigned char *buf_addr = NULL;
2237
2238 DEBUG_PRINT_HIGH("\n Inside use_output_buffer()");
2239 if(bytes != m_sOutPortDef.nBufferSize || secure_session)
2240 {
2241 DEBUG_PRINT_ERROR("\nERROR: use_output_buffer: Size Mismatch!! "
2242 "bytes[%d] != Port.nBufferSize[%d]", bytes, m_sOutPortDef.nBufferSize);
2243 return OMX_ErrorBadParameter;
2244 }
2245
2246 if(!m_out_mem_ptr)
2247 {
2248 output_use_buffer = true;
2249 int nBufHdrSize = 0;
2250
2251 DEBUG_PRINT_LOW("Allocating First Output Buffer(%d)\n",m_sOutPortDef.nBufferCountActual);
2252 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
2253 /*
2254 * Memory for output side involves the following:
2255 * 1. Array of Buffer Headers
2256 * 2. Bitmask array to hold the buffer allocation details
2257 * In order to minimize the memory management entire allocation
2258 * is done in one step.
2259 */
2260 //OMX Buffer header
2261 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
2262 if(m_out_mem_ptr == NULL)
2263 {
2264 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_out_mem_ptr");
2265 return OMX_ErrorInsufficientResources;
2266 }
2267
2268 m_pOutput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sOutPortDef.nBufferCountActual);
2269 if(m_pOutput_pmem == NULL)
2270 {
2271 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
2272 return OMX_ErrorInsufficientResources;
2273 }
2274 #ifdef USE_ION
2275 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
2276 if(m_pOutput_ion == NULL)
2277 {
2278 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
2279 return OMX_ErrorInsufficientResources;
2280 }
2281 #endif
2282 if(m_out_mem_ptr)
2283 {
2284 bufHdr = m_out_mem_ptr;
2285 DEBUG_PRINT_LOW("Memory Allocation Succeeded for OUT port%p\n",m_out_mem_ptr);
2286 // Settting the entire storage nicely
2287 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
2288 {
2289 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2290 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
2291 bufHdr->nAllocLen = bytes;
2292 bufHdr->nFilledLen = 0;
2293 bufHdr->pAppPrivate = appData;
2294 bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
2295 bufHdr->pBuffer = NULL;
2296 bufHdr++;
2297 m_pOutput_pmem[i].fd = -1;
2298 #ifdef USE_ION
2299 m_pOutput_ion[i].ion_device_fd =-1;
2300 m_pOutput_ion[i].fd_ion_data.fd=-1;
2301 m_pOutput_ion[i].ion_alloc_data.handle =NULL;
2302 #endif
2303 }
2304 }
2305 else
2306 {
2307 DEBUG_PRINT_ERROR("ERROR: Output buf mem alloc failed[0x%x]\n",m_out_mem_ptr);
2308 eRet = OMX_ErrorInsufficientResources;
2309 }
2310 }
2311
2312 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
2313 {
2314 if(BITMASK_ABSENT(&m_out_bm_count,i))
2315 {
2316 break;
2317 }
2318 }
2319
2320 if(eRet == OMX_ErrorNone)
2321 {
2322 if(i < m_sOutPortDef.nBufferCountActual)
2323 {
2324 *bufferHdr = (m_out_mem_ptr + i );
2325 (*bufferHdr)->pBuffer = (OMX_U8 *)buffer;
2326 (*bufferHdr)->pAppPrivate = appData;
2327 BITMASK_SET(&m_out_bm_count,i);
2328
2329 if(!m_use_output_pmem)
2330 {
2331 #ifdef USE_ION
2332 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(
2333 m_sOutPortDef.nBufferSize,
2334 &m_pOutput_ion[i].ion_alloc_data,
2335 &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2336 if(m_pOutput_ion[i].ion_device_fd < 0) {
2337 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2338 return OMX_ErrorInsufficientResources;
2339 }
2340 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
2341 #else
2342 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2343
2344 if(m_pOutput_pmem[i].fd == 0)
2345 {
2346 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2347 }
2348
2349 if(m_pOutput_pmem[i].fd < 0)
2350 {
2351 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed");
2352 return OMX_ErrorInsufficientResources;
2353 }
2354 #endif
2355 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2356 m_pOutput_pmem[i].offset = 0;
2357 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
2358 MAP_SHARED,m_pOutput_pmem[i].fd,0);
2359 if(m_pOutput_pmem[i].buffer == MAP_FAILED)
2360 {
2361 DEBUG_PRINT_ERROR("\nERROR: mmap() Failed");
2362 close(m_pOutput_pmem[i].fd);
2363 #ifdef USE_ION
2364 free_ion_memory(&m_pOutput_ion[i]);
2365 #endif
2366 return OMX_ErrorInsufficientResources;
2367 }
2368 }
2369 else
2370 {
2371 OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO *pParam = reinterpret_cast<OMX_QCOM_PLATFORM_PRIVATE_PMEM_INFO*>((*bufferHdr)->pAppPrivate);
2372 DEBUG_PRINT_LOW("Inside qcom_ext pParam:0x%x )", pParam);
2373
2374 if(pParam)
2375 {
2376 DEBUG_PRINT_LOW("Inside qcom_ext with luma:(fd:%d,offset:0x%x)", pParam->pmem_fd, pParam->offset);
2377 m_pOutput_pmem[i].fd = pParam->pmem_fd;
2378 m_pOutput_pmem[i].offset = pParam->offset;
2379 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2380 m_pOutput_pmem[i].buffer = (unsigned char *)buffer;
2381 }
2382 else
2383 {
2384 DEBUG_PRINT_ERROR("ERROR: Invalid AppData given for PMEM o/p UseBuffer case");
2385 return OMX_ErrorBadParameter;
2386 }
2387 buf_addr = (unsigned char *)buffer;
2388 }
2389
2390 DEBUG_PRINT_LOW("\n use_out:: bufhdr = %p, pBuffer = %p, m_pOutput_pmem[i].buffer = %p",
2391 (*bufferHdr), (*bufferHdr)->pBuffer, m_pOutput_pmem[i].buffer);
2392 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
2393 {
2394 DEBUG_PRINT_ERROR("ERROR: dev_use_buf Failed for o/p buf");
2395 return OMX_ErrorInsufficientResources;
2396 }
2397 }
2398 else
2399 {
2400 DEBUG_PRINT_ERROR("ERROR: All o/p Buffers have been Used, invalid use_buf call for "
2401 "index = %u", i);
2402 eRet = OMX_ErrorInsufficientResources;
2403 }
2404 }
2405 return eRet;
2406 }
2407
2408
2409 /* ======================================================================
2410 FUNCTION
2411 omx_video::UseBuffer
2412
2413 DESCRIPTION
2414 OMX Use Buffer method implementation.
2415
2416 PARAMETERS
2417 <TBD>.
2418
2419 RETURN VALUE
2420 OMX Error None , if everything successful.
2421
2422 ========================================================================== */
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)2423 OMX_ERRORTYPE omx_video::use_buffer(
2424 OMX_IN OMX_HANDLETYPE hComp,
2425 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2426 OMX_IN OMX_U32 port,
2427 OMX_IN OMX_PTR appData,
2428 OMX_IN OMX_U32 bytes,
2429 OMX_IN OMX_U8* buffer)
2430 {
2431 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2432 if(m_state == OMX_StateInvalid)
2433 {
2434 DEBUG_PRINT_ERROR("ERROR: Use Buffer in Invalid State\n");
2435 return OMX_ErrorInvalidState;
2436 }
2437 if(port == PORT_INDEX_IN)
2438 {
2439 eRet = use_input_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2440 }
2441 else if(port == PORT_INDEX_OUT)
2442 {
2443 eRet = use_output_buffer(hComp,bufferHdr,port,appData,bytes,buffer);
2444 }
2445 else
2446 {
2447 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
2448 eRet = OMX_ErrorBadPortIndex;
2449 }
2450
2451 if(eRet == OMX_ErrorNone)
2452 {
2453 if(allocate_done())
2454 {
2455 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
2456 {
2457 // Send the callback now
2458 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
2459 post_event(OMX_CommandStateSet,OMX_StateIdle,
2460 OMX_COMPONENT_GENERATE_EVENT);
2461 }
2462 }
2463 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
2464 {
2465 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
2466 {
2467 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
2468 post_event(OMX_CommandPortEnable,
2469 PORT_INDEX_IN,
2470 OMX_COMPONENT_GENERATE_EVENT);
2471 }
2472
2473 }
2474 else if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
2475 {
2476 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
2477 {
2478 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
2479 post_event(OMX_CommandPortEnable,
2480 PORT_INDEX_OUT,
2481 OMX_COMPONENT_GENERATE_EVENT);
2482 m_event_port_settings_sent = false;
2483 }
2484 }
2485 }
2486 return eRet;
2487 }
2488
free_input_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)2489 OMX_ERRORTYPE omx_video::free_input_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
2490 {
2491 unsigned int index = 0;
2492 OMX_U8 *temp_buff ;
2493
2494 if(bufferHdr == NULL || m_inp_mem_ptr == NULL)
2495 {
2496 DEBUG_PRINT_ERROR("ERROR: free_input: Invalid bufferHdr[%p] or m_inp_mem_ptr[%p]",
2497 bufferHdr, m_inp_mem_ptr);
2498 return OMX_ErrorBadParameter;
2499 }
2500
2501 index = bufferHdr - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
2502 #ifdef _ANDROID_ICS_
2503 if(meta_mode_enable)
2504 {
2505 if(index < m_sInPortDef.nBufferCountActual)
2506 {
2507 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
2508 memset(&meta_buffers[index], 0, sizeof(meta_buffers[index]));
2509 }
2510 if(!mUseProxyColorFormat)
2511 return OMX_ErrorNone;
2512 else {
2513 c2d_conv.close();
2514 opaque_buffer_hdr[index] = NULL;
2515 }
2516 }
2517 #endif
2518 if(index < m_sInPortDef.nBufferCountActual && !mUseProxyColorFormat &&
2519 dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
2520 {
2521 DEBUG_PRINT_LOW("\nERROR: dev_free_buf() Failed for i/p buf");
2522 }
2523
2524 if(index < m_sInPortDef.nBufferCountActual && m_pInput_pmem)
2525 {
2526 if(m_pInput_pmem[index].fd > 0 && input_use_buffer == false)
2527 {
2528 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p AllocateBuffer case");
2529 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
2530 close (m_pInput_pmem[index].fd);
2531 #ifdef USE_ION
2532 free_ion_memory(&m_pInput_ion[index]);
2533 #endif
2534 m_pInput_pmem[index].fd = -1;
2535 }
2536 else if(m_pInput_pmem[index].fd > 0 && (input_use_buffer == true &&
2537 m_use_input_pmem == OMX_FALSE))
2538 {
2539 DEBUG_PRINT_LOW("\n FreeBuffer:: i/p Heap UseBuffer case");
2540 if(dev_free_buf(&m_pInput_pmem[index],PORT_INDEX_IN) != true)
2541 {
2542 DEBUG_PRINT_ERROR("\nERROR: dev_free_buf() Failed for i/p buf");
2543 }
2544 munmap (m_pInput_pmem[index].buffer,m_pInput_pmem[index].size);
2545 close (m_pInput_pmem[index].fd);
2546 #ifdef USE_ION
2547 free_ion_memory(&m_pInput_ion[index]);
2548 #endif
2549 m_pInput_pmem[index].fd = -1;
2550 }
2551 else
2552 {
2553 DEBUG_PRINT_ERROR("\n FreeBuffer:: fd is invalid or i/p PMEM UseBuffer case");
2554 }
2555 }
2556 return OMX_ErrorNone;
2557 }
2558
free_output_buffer(OMX_BUFFERHEADERTYPE * bufferHdr)2559 OMX_ERRORTYPE omx_video::free_output_buffer(OMX_BUFFERHEADERTYPE *bufferHdr)
2560 {
2561 unsigned int index = 0;
2562 OMX_U8 *temp_buff ;
2563
2564 if(bufferHdr == NULL || m_out_mem_ptr == NULL)
2565 {
2566 DEBUG_PRINT_ERROR("ERROR: free_output: Invalid bufferHdr[%p] or m_out_mem_ptr[%p]",
2567 bufferHdr, m_out_mem_ptr);
2568 return OMX_ErrorBadParameter;
2569 }
2570 index = bufferHdr - m_out_mem_ptr;
2571
2572 if(index < m_sOutPortDef.nBufferCountActual &&
2573 dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
2574 {
2575 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
2576 }
2577
2578 if(index < m_sOutPortDef.nBufferCountActual && m_pOutput_pmem)
2579 {
2580 if(m_pOutput_pmem[index].fd > 0 && output_use_buffer == false )
2581 {
2582 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p AllocateBuffer case");
2583 if(!secure_session)
2584 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
2585 close (m_pOutput_pmem[index].fd);
2586 #ifdef USE_ION
2587 free_ion_memory(&m_pOutput_ion[index]);
2588 #endif
2589 m_pOutput_pmem[index].fd = -1;
2590 }
2591 else if( m_pOutput_pmem[index].fd > 0 && (output_use_buffer == true
2592 && m_use_output_pmem == OMX_FALSE))
2593 {
2594 DEBUG_PRINT_LOW("\n FreeBuffer:: o/p Heap UseBuffer case");
2595 if(dev_free_buf(&m_pOutput_pmem[index],PORT_INDEX_OUT) != true)
2596 {
2597 DEBUG_PRINT_ERROR("ERROR: dev_free_buf Failed for o/p buf");
2598 }
2599 munmap (m_pOutput_pmem[index].buffer,m_pOutput_pmem[index].size);
2600 close (m_pOutput_pmem[index].fd);
2601 #ifdef USE_ION
2602 free_ion_memory(&m_pOutput_ion[index]);
2603 #endif
2604 m_pOutput_pmem[index].fd = -1;
2605 }
2606 else
2607 {
2608 DEBUG_PRINT_LOW("\n FreeBuffer:: fd is invalid or o/p PMEM UseBuffer case");
2609 }
2610 }
2611 return OMX_ErrorNone;
2612 }
2613 #ifdef _ANDROID_ICS_
allocate_input_meta_buffer(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE ** bufferHdr,OMX_PTR appData,OMX_U32 bytes)2614 OMX_ERRORTYPE omx_video::allocate_input_meta_buffer(
2615 OMX_HANDLETYPE hComp,
2616 OMX_BUFFERHEADERTYPE **bufferHdr,
2617 OMX_PTR appData,
2618 OMX_U32 bytes)
2619 {
2620 unsigned index = 0;
2621 if(!bufferHdr || bytes != sizeof(encoder_media_buffer_type))
2622 {
2623 DEBUG_PRINT_ERROR("wrong params allocate_input_meta_buffer Hdr %p len %d",
2624 bufferHdr,bytes);
2625 return OMX_ErrorBadParameter;
2626 }
2627 if(!m_inp_mem_ptr && !mUseProxyColorFormat)
2628 m_inp_mem_ptr = meta_buffer_hdr;
2629 for(index = 0;((index < m_sInPortDef.nBufferCountActual) &&
2630 meta_buffer_hdr[index].pBuffer); index++);
2631 if(index == m_sInPortDef.nBufferCountActual)
2632 {
2633 DEBUG_PRINT_ERROR("All buffers are allocated input_meta_buffer");
2634 return OMX_ErrorBadParameter;
2635 }
2636 if(mUseProxyColorFormat){
2637 if(opaque_buffer_hdr[index]){
2638 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
2639 return OMX_ErrorBadParameter;
2640 }
2641 if(allocate_input_buffer(hComp,&opaque_buffer_hdr[index],
2642 PORT_INDEX_IN,appData,m_sInPortDef.nBufferSize) != OMX_ErrorNone) {
2643 DEBUG_PRINT_ERROR("All buffers are allocated opaque_buffer_hdr");
2644 return OMX_ErrorBadParameter;
2645 }
2646 }
2647 BITMASK_SET(&m_inp_bm_count,index);
2648 *bufferHdr = &meta_buffer_hdr[index];
2649 memset(&meta_buffer_hdr[index], 0, sizeof(meta_buffer_hdr[index]));
2650 meta_buffer_hdr[index].nSize = sizeof(meta_buffer_hdr[index]);
2651 meta_buffer_hdr[index].nAllocLen = sizeof(meta_buffers[index]);
2652 meta_buffer_hdr[index].nVersion.nVersion = OMX_SPEC_VERSION;
2653 meta_buffer_hdr[index].nInputPortIndex = PORT_INDEX_IN;
2654 meta_buffer_hdr[index].pBuffer = (OMX_U8*)&meta_buffers[index];
2655 meta_buffer_hdr[index].pAppPrivate = appData;
2656 if(mUseProxyColorFormat) {
2657 m_opq_pmem_q.insert_entry((unsigned int)opaque_buffer_hdr[index],0,0);
2658 DEBUG_PRINT_HIGH("\n opaque_buffer_hdr insert %p", opaque_buffer_hdr[index]);
2659 }
2660 return OMX_ErrorNone;
2661 }
2662 #endif
2663 /* ======================================================================
2664 FUNCTION
2665 omx_venc::AllocateInputBuffer
2666
2667 DESCRIPTION
2668 Helper function for allocate buffer in the input pin
2669
2670 PARAMETERS
2671 None.
2672
2673 RETURN VALUE
2674 true/false
2675
2676 ========================================================================== */
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)2677 OMX_ERRORTYPE omx_video::allocate_input_buffer(
2678 OMX_IN OMX_HANDLETYPE hComp,
2679 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2680 OMX_IN OMX_U32 port,
2681 OMX_IN OMX_PTR appData,
2682 OMX_IN OMX_U32 bytes)
2683 {
2684
2685 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2686 unsigned i = 0;
2687
2688 DEBUG_PRINT_HIGH("\n allocate_input_buffer()::");
2689 if(bytes != m_sInPortDef.nBufferSize || secure_session)
2690 {
2691 DEBUG_PRINT_ERROR("\nERROR: Buffer size mismatch error: bytes[%u] != nBufferSize[%u]\n",
2692 bytes, m_sInPortDef.nBufferSize);
2693 return OMX_ErrorBadParameter;
2694 }
2695
2696 if(!m_inp_mem_ptr)
2697 {
2698 DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
2699 m_sInPortDef.nBufferSize, m_sInPortDef.nBufferCountActual);
2700 m_inp_mem_ptr = (OMX_BUFFERHEADERTYPE*) \
2701 calloc( (sizeof(OMX_BUFFERHEADERTYPE)), m_sInPortDef.nBufferCountActual);
2702 if(m_inp_mem_ptr == NULL)
2703 {
2704 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_inp_mem_ptr");
2705 return OMX_ErrorInsufficientResources;
2706 }
2707
2708 m_pInput_pmem = (struct pmem *) calloc(sizeof (struct pmem), m_sInPortDef.nBufferCountActual);
2709
2710 if(m_pInput_pmem == NULL)
2711 {
2712 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_pmem");
2713 return OMX_ErrorInsufficientResources;
2714 }
2715 #ifdef USE_ION
2716 m_pInput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sInPortDef.nBufferCountActual);
2717 if(m_pInput_ion == NULL)
2718 {
2719 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pInput_ion");
2720 return OMX_ErrorInsufficientResources;
2721 }
2722 #endif
2723 for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2724 {
2725 m_pInput_pmem[i].fd = -1;
2726 #ifdef USE_ION
2727 m_pInput_ion[i].ion_device_fd =-1;
2728 m_pInput_ion[i].fd_ion_data.fd =-1;
2729 m_pInput_ion[i].ion_alloc_data.handle=NULL;
2730 #endif
2731 }
2732 }
2733
2734 for(i=0; i< m_sInPortDef.nBufferCountActual; i++)
2735 {
2736 if(BITMASK_ABSENT(&m_inp_bm_count,i))
2737 {
2738 break;
2739 }
2740 }
2741 if(i < m_sInPortDef.nBufferCountActual)
2742 {
2743
2744 *bufferHdr = (m_inp_mem_ptr + i);
2745 (*bufferHdr)->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2746 (*bufferHdr)->nVersion.nVersion = OMX_SPEC_VERSION;
2747 (*bufferHdr)->nAllocLen = m_sInPortDef.nBufferSize;
2748 (*bufferHdr)->pAppPrivate = appData;
2749 (*bufferHdr)->nInputPortIndex = PORT_INDEX_IN;
2750
2751 #ifdef USE_ION
2752 m_pInput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sInPortDef.nBufferSize,
2753 &m_pInput_ion[i].ion_alloc_data,
2754 &m_pInput_ion[i].fd_ion_data,0);
2755 if(m_pInput_ion[i].ion_device_fd < 0) {
2756 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2757 return OMX_ErrorInsufficientResources;
2758 }
2759
2760 m_pInput_pmem[i].fd = m_pInput_ion[i].fd_ion_data.fd;
2761 #else
2762 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2763
2764 if(m_pInput_pmem[i].fd == 0)
2765 {
2766 m_pInput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2767 }
2768
2769 if(m_pInput_pmem[i].fd < 0)
2770 {
2771 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() Failed\n");
2772 return OMX_ErrorInsufficientResources;
2773 }
2774 #endif
2775 m_pInput_pmem[i].size = m_sInPortDef.nBufferSize;
2776 m_pInput_pmem[i].offset = 0;
2777
2778 m_pInput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pInput_pmem[i].size,PROT_READ|PROT_WRITE,
2779 MAP_SHARED,m_pInput_pmem[i].fd,0);
2780 if(m_pInput_pmem[i].buffer == MAP_FAILED)
2781 {
2782 DEBUG_PRINT_ERROR("\nERROR: mmap FAILED= %d\n", errno);
2783 close(m_pInput_pmem[i].fd);
2784 #ifdef USE_ION
2785 free_ion_memory(&m_pInput_ion[i]);
2786 #endif
2787 return OMX_ErrorInsufficientResources;
2788 }
2789
2790 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pInput_pmem[i].buffer;
2791 DEBUG_PRINT_LOW("\n Virtual address in allocate buffer is %p", m_pInput_pmem[i].buffer);
2792 BITMASK_SET(&m_inp_bm_count,i);
2793 //here change the I/P param here from buf_adr to pmem
2794 if(!mUseProxyColorFormat && (dev_use_buf(&m_pInput_pmem[i],PORT_INDEX_IN,i) != true))
2795 {
2796 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for i/p buf\n");
2797 return OMX_ErrorInsufficientResources;
2798 }
2799 }
2800 else
2801 {
2802 DEBUG_PRINT_ERROR("\nERROR: All i/p buffers are allocated, invalid allocate buf call"
2803 "for index [%d]\n", i);
2804 eRet = OMX_ErrorInsufficientResources;
2805 }
2806
2807 return eRet;
2808 }
2809
2810
2811 /* ======================================================================
2812 FUNCTION
2813 omx_venc::AllocateOutputBuffer
2814
2815 DESCRIPTION
2816 Helper fn for AllocateBuffer in the output pin
2817
2818 PARAMETERS
2819 <TBD>.
2820
2821 RETURN VALUE
2822 OMX Error None if everything went well.
2823
2824 ========================================================================== */
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)2825 OMX_ERRORTYPE omx_video::allocate_output_buffer(
2826 OMX_IN OMX_HANDLETYPE hComp,
2827 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2828 OMX_IN OMX_U32 port,
2829 OMX_IN OMX_PTR appData,
2830 OMX_IN OMX_U32 bytes)
2831 {
2832 OMX_ERRORTYPE eRet = OMX_ErrorNone;
2833 OMX_BUFFERHEADERTYPE *bufHdr= NULL; // buffer header
2834 unsigned i= 0; // Temporary counter
2835
2836 DEBUG_PRINT_HIGH("\n allocate_output_buffer()::");
2837 if(!m_out_mem_ptr)
2838 {
2839 int nBufHdrSize = 0;
2840 DEBUG_PRINT_HIGH("%s: size = %d, actual cnt %d", __FUNCTION__,
2841 m_sOutPortDef.nBufferSize, m_sOutPortDef.nBufferCountActual);
2842 nBufHdrSize = m_sOutPortDef.nBufferCountActual * sizeof(OMX_BUFFERHEADERTYPE);
2843
2844 /*
2845 * Memory for output side involves the following:
2846 * 1. Array of Buffer Headers
2847 * 2. Bitmask array to hold the buffer allocation details
2848 * In order to minimize the memory management entire allocation
2849 * is done in one step.
2850 */
2851 m_out_mem_ptr = (OMX_BUFFERHEADERTYPE *)calloc(nBufHdrSize,1);
2852
2853 #ifdef USE_ION
2854 m_pOutput_ion = (struct venc_ion *) calloc(sizeof (struct venc_ion), m_sOutPortDef.nBufferCountActual);
2855 if(m_pOutput_ion == NULL)
2856 {
2857 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_ion");
2858 return OMX_ErrorInsufficientResources;
2859 }
2860 #endif
2861 m_pOutput_pmem = (struct pmem *) calloc(sizeof(struct pmem), m_sOutPortDef.nBufferCountActual);
2862 if(m_pOutput_pmem == NULL)
2863 {
2864 DEBUG_PRINT_ERROR("\nERROR: calloc() Failed for m_pOutput_pmem");
2865 return OMX_ErrorInsufficientResources;
2866 }
2867 if(m_out_mem_ptr && m_pOutput_pmem)
2868 {
2869 bufHdr = m_out_mem_ptr;
2870
2871 for(i=0; i < m_sOutPortDef.nBufferCountActual ; i++)
2872 {
2873 bufHdr->nSize = sizeof(OMX_BUFFERHEADERTYPE);
2874 bufHdr->nVersion.nVersion = OMX_SPEC_VERSION;
2875 // Set the values when we determine the right HxW param
2876 bufHdr->nAllocLen = m_sOutPortDef.nBufferSize;
2877 bufHdr->nFilledLen = 0;
2878 bufHdr->pAppPrivate = appData;
2879 bufHdr->nOutputPortIndex = PORT_INDEX_OUT;
2880 bufHdr->pBuffer = NULL;
2881 bufHdr++;
2882 m_pOutput_pmem[i].fd = -1;
2883 #ifdef USE_ION
2884 m_pOutput_ion[i].ion_device_fd =-1;
2885 m_pOutput_ion[i].fd_ion_data.fd=-1;
2886 m_pOutput_ion[i].ion_alloc_data.handle =NULL;
2887 #endif
2888 }
2889 }
2890 else
2891 {
2892 DEBUG_PRINT_ERROR("ERROR: calloc() failed for m_out_mem_ptr/m_pOutput_pmem");
2893 eRet = OMX_ErrorInsufficientResources;
2894 }
2895 }
2896
2897 DEBUG_PRINT_HIGH("\n actual cnt = %u", m_sOutPortDef.nBufferCountActual);
2898 for(i=0; i< m_sOutPortDef.nBufferCountActual; i++)
2899 {
2900 if(BITMASK_ABSENT(&m_out_bm_count,i))
2901 {
2902 DEBUG_PRINT_LOW("\n Found a Free Output Buffer %d",i);
2903 break;
2904 }
2905 }
2906 if(eRet == OMX_ErrorNone)
2907 {
2908 if(i < m_sOutPortDef.nBufferCountActual)
2909 {
2910 #ifdef USE_ION
2911 m_pOutput_ion[i].ion_device_fd = alloc_map_ion_memory(m_sOutPortDef.nBufferSize,
2912 &m_pOutput_ion[i].ion_alloc_data,
2913 &m_pOutput_ion[i].fd_ion_data,ION_FLAG_CACHED);
2914 if(m_pOutput_ion[i].ion_device_fd < 0) {
2915 DEBUG_PRINT_ERROR("\nERROR:ION device open() Failed");
2916 return OMX_ErrorInsufficientResources;
2917 }
2918 m_pOutput_pmem[i].fd = m_pOutput_ion[i].fd_ion_data.fd;
2919 #else
2920 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2921 if(m_pOutput_pmem[i].fd == 0)
2922 {
2923 m_pOutput_pmem[i].fd = open (MEM_DEVICE,O_RDWR);
2924 }
2925
2926 if(m_pOutput_pmem[i].fd < 0)
2927 {
2928 DEBUG_PRINT_ERROR("\nERROR: /dev/pmem_adsp open() failed");
2929 return OMX_ErrorInsufficientResources;
2930 }
2931 #endif
2932 m_pOutput_pmem[i].size = m_sOutPortDef.nBufferSize;
2933 m_pOutput_pmem[i].offset = 0;
2934 if(!secure_session) {
2935 m_pOutput_pmem[i].buffer = (unsigned char *)mmap(NULL,m_pOutput_pmem[i].size,PROT_READ|PROT_WRITE,
2936 MAP_SHARED,m_pOutput_pmem[i].fd,0);
2937 if(m_pOutput_pmem[i].buffer == MAP_FAILED)
2938 {
2939 DEBUG_PRINT_ERROR("\nERROR: MMAP_FAILED in o/p alloc buffer");
2940 close (m_pOutput_pmem[i].fd);
2941 #ifdef USE_ION
2942 free_ion_memory(&m_pOutput_ion[i]);
2943 #endif
2944 return OMX_ErrorInsufficientResources;
2945 }
2946 }
2947
2948 *bufferHdr = (m_out_mem_ptr + i );
2949 if(!secure_session)
2950 (*bufferHdr)->pBuffer = (OMX_U8 *)m_pOutput_pmem[i].buffer;
2951 else {
2952 m_pOutput_pmem[i].buffer = (OMX_U8 *)(i + 12345);
2953 (*bufferHdr)->pBuffer = (OMX_U8 *)(i + 12345);
2954 }
2955 (*bufferHdr)->pAppPrivate = appData;
2956
2957 BITMASK_SET(&m_out_bm_count,i);
2958
2959 if(dev_use_buf(&m_pOutput_pmem[i],PORT_INDEX_OUT,i) != true)
2960 {
2961 DEBUG_PRINT_ERROR("\nERROR: dev_use_buf FAILED for o/p buf");
2962 return OMX_ErrorInsufficientResources;
2963 }
2964 }
2965 else
2966 {
2967 DEBUG_PRINT_ERROR("\nERROR: All o/p buffers are allocated, invalid allocate buf call"
2968 "for index [%d]\n", i);
2969 }
2970 }
2971
2972 return eRet;
2973 }
2974
2975
2976 // AllocateBuffer -- API Call
2977 /* ======================================================================
2978 FUNCTION
2979 omx_video::AllocateBuffer
2980
2981 DESCRIPTION
2982 Returns zero if all the buffers released..
2983
2984 PARAMETERS
2985 None.
2986
2987 RETURN VALUE
2988 true/false
2989
2990 ========================================================================== */
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)2991 OMX_ERRORTYPE omx_video::allocate_buffer(OMX_IN OMX_HANDLETYPE hComp,
2992 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
2993 OMX_IN OMX_U32 port,
2994 OMX_IN OMX_PTR appData,
2995 OMX_IN OMX_U32 bytes)
2996 {
2997
2998 OMX_ERRORTYPE eRet = OMX_ErrorNone; // OMX return type
2999
3000 DEBUG_PRINT_LOW("\n Allocate buffer of size = %d on port %d \n", bytes, (int)port);
3001 if(m_state == OMX_StateInvalid)
3002 {
3003 DEBUG_PRINT_ERROR("ERROR: Allocate Buf in Invalid State\n");
3004 return OMX_ErrorInvalidState;
3005 }
3006
3007 // What if the client calls again.
3008 if(port == PORT_INDEX_IN)
3009 {
3010 #ifdef _ANDROID_ICS_
3011 if(meta_mode_enable)
3012 eRet = allocate_input_meta_buffer(hComp,bufferHdr,appData,bytes);
3013 else
3014 #endif
3015 eRet = allocate_input_buffer(hComp,bufferHdr,port,appData,bytes);
3016 }
3017 else if(port == PORT_INDEX_OUT)
3018 {
3019 eRet = allocate_output_buffer(hComp,bufferHdr,port,appData,bytes);
3020 }
3021 else
3022 {
3023 DEBUG_PRINT_ERROR("ERROR: Invalid Port Index received %d\n",(int)port);
3024 eRet = OMX_ErrorBadPortIndex;
3025 }
3026 DEBUG_PRINT_LOW("Checking for Output Allocate buffer Done");
3027 if(eRet == OMX_ErrorNone)
3028 {
3029 if(allocate_done())
3030 {
3031 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_IDLE_PENDING))
3032 {
3033 // Send the callback now
3034 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_IDLE_PENDING);
3035 post_event(OMX_CommandStateSet,OMX_StateIdle,
3036 OMX_COMPONENT_GENERATE_EVENT);
3037 }
3038 }
3039 if(port == PORT_INDEX_IN && m_sInPortDef.bPopulated)
3040 {
3041 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_INPUT_ENABLE_PENDING))
3042 {
3043 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_ENABLE_PENDING);
3044 post_event(OMX_CommandPortEnable,
3045 PORT_INDEX_IN,
3046 OMX_COMPONENT_GENERATE_EVENT);
3047 }
3048 }
3049 if(port == PORT_INDEX_OUT && m_sOutPortDef.bPopulated)
3050 {
3051 if(BITMASK_PRESENT(&m_flags,OMX_COMPONENT_OUTPUT_ENABLE_PENDING))
3052 {
3053 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_ENABLE_PENDING);
3054 post_event(OMX_CommandPortEnable,
3055 PORT_INDEX_OUT,
3056 OMX_COMPONENT_GENERATE_EVENT);
3057 m_event_port_settings_sent = false;
3058 }
3059 }
3060 }
3061 DEBUG_PRINT_LOW("Allocate Buffer exit with ret Code %d\n",eRet);
3062 return eRet;
3063 }
3064
3065
3066 // Free Buffer - API call
3067 /* ======================================================================
3068 FUNCTION
3069 omx_video::FreeBuffer
3070
3071 DESCRIPTION
3072
3073 PARAMETERS
3074 None.
3075
3076 RETURN VALUE
3077 true/false
3078
3079 ========================================================================== */
free_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_U32 port,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3080 OMX_ERRORTYPE omx_video::free_buffer(OMX_IN OMX_HANDLETYPE hComp,
3081 OMX_IN OMX_U32 port,
3082 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3083 {
3084 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3085 unsigned int nPortIndex;
3086
3087 DEBUG_PRINT_LOW("In for decoder free_buffer \n");
3088
3089 if(m_state == OMX_StateIdle &&
3090 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3091 {
3092 DEBUG_PRINT_LOW(" free buffer while Component in Loading pending\n");
3093 }
3094 else if((m_sInPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_IN)||
3095 (m_sOutPortDef.bEnabled == OMX_FALSE && port == PORT_INDEX_OUT))
3096 {
3097 DEBUG_PRINT_LOW("Free Buffer while port %d disabled\n", port);
3098 }
3099 else if(m_state == OMX_StateExecuting || m_state == OMX_StatePause)
3100 {
3101 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,ports need to be disabled\n");
3102 post_event(OMX_EventError,
3103 OMX_ErrorPortUnpopulated,
3104 OMX_COMPONENT_GENERATE_EVENT);
3105
3106 return eRet;
3107 }
3108 else
3109 {
3110 DEBUG_PRINT_ERROR("ERROR: Invalid state to free buffer,port lost Buffers\n");
3111 post_event(OMX_EventError,
3112 OMX_ErrorPortUnpopulated,
3113 OMX_COMPONENT_GENERATE_EVENT);
3114 }
3115
3116 if(port == PORT_INDEX_IN)
3117 {
3118 // check if the buffer is valid
3119 nPortIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
3120
3121 DEBUG_PRINT_LOW("free_buffer on i/p port - Port idx %d, actual cnt %d \n",
3122 nPortIndex, m_sInPortDef.nBufferCountActual);
3123 if(nPortIndex < m_sInPortDef.nBufferCountActual)
3124 {
3125 // Clear the bit associated with it.
3126 BITMASK_CLEAR(&m_inp_bm_count,nPortIndex);
3127 free_input_buffer (buffer);
3128 m_sInPortDef.bPopulated = OMX_FALSE;
3129
3130 /*Free the Buffer Header*/
3131 if(release_input_done()
3132 #ifdef _ANDROID_ICS_
3133 && !meta_mode_enable
3134 #endif
3135 )
3136 {
3137 input_use_buffer = false;
3138 if(m_inp_mem_ptr)
3139 {
3140 DEBUG_PRINT_LOW("Freeing m_inp_mem_ptr\n");
3141 free (m_inp_mem_ptr);
3142 m_inp_mem_ptr = NULL;
3143 }
3144 if(m_pInput_pmem)
3145 {
3146 DEBUG_PRINT_LOW("Freeing m_pInput_pmem\n");
3147 free(m_pInput_pmem);
3148 m_pInput_pmem = NULL;
3149 }
3150 #ifdef USE_ION
3151 if(m_pInput_ion)
3152 {
3153 DEBUG_PRINT_LOW("Freeing m_pInput_ion\n");
3154 free(m_pInput_ion);
3155 m_pInput_ion = NULL;
3156 }
3157 #endif
3158 }
3159 }
3160 else
3161 {
3162 DEBUG_PRINT_ERROR("ERROR: free_buffer ,Port Index Invalid\n");
3163 eRet = OMX_ErrorBadPortIndex;
3164 }
3165
3166 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING)
3167 && release_input_done())
3168 {
3169 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
3170 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_INPUT_DISABLE_PENDING);
3171 post_event(OMX_CommandPortDisable,
3172 PORT_INDEX_IN,
3173 OMX_COMPONENT_GENERATE_EVENT);
3174 }
3175 }
3176 else if(port == PORT_INDEX_OUT)
3177 {
3178 // check if the buffer is valid
3179 nPortIndex = buffer - (OMX_BUFFERHEADERTYPE*)m_out_mem_ptr;
3180
3181 DEBUG_PRINT_LOW("free_buffer on o/p port - Port idx %d, actual cnt %d \n",
3182 nPortIndex, m_sOutPortDef.nBufferCountActual);
3183 if(nPortIndex < m_sOutPortDef.nBufferCountActual)
3184 {
3185 // Clear the bit associated with it.
3186 BITMASK_CLEAR(&m_out_bm_count,nPortIndex);
3187 m_sOutPortDef.bPopulated = OMX_FALSE;
3188 free_output_buffer (buffer);
3189
3190 if(release_output_done())
3191 {
3192 output_use_buffer = false;
3193 if(m_out_mem_ptr)
3194 {
3195 DEBUG_PRINT_LOW("Freeing m_out_mem_ptr\n");
3196 free (m_out_mem_ptr);
3197 m_out_mem_ptr = NULL;
3198 }
3199 if(m_pOutput_pmem)
3200 {
3201 DEBUG_PRINT_LOW("Freeing m_pOutput_pmem\n");
3202 free(m_pOutput_pmem);
3203 m_pOutput_pmem = NULL;
3204 }
3205 #ifdef USE_ION
3206 if(m_pOutput_ion)
3207 {
3208 DEBUG_PRINT_LOW("Freeing m_pOutput_ion\n");
3209 free(m_pOutput_ion);
3210 m_pOutput_ion = NULL;
3211 }
3212 #endif
3213 }
3214 }
3215 else
3216 {
3217 DEBUG_PRINT_ERROR("ERROR: free_buffer , Port Index Invalid\n");
3218 eRet = OMX_ErrorBadPortIndex;
3219 }
3220 if(BITMASK_PRESENT((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING)
3221 && release_output_done() )
3222 {
3223 DEBUG_PRINT_LOW("FreeBuffer : If any Disable event pending,post it\n");
3224
3225 DEBUG_PRINT_LOW("MOVING TO DISABLED STATE \n");
3226 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_OUTPUT_DISABLE_PENDING);
3227 post_event(OMX_CommandPortDisable,
3228 PORT_INDEX_OUT,
3229 OMX_COMPONENT_GENERATE_EVENT);
3230
3231 }
3232 }
3233 else
3234 {
3235 eRet = OMX_ErrorBadPortIndex;
3236 }
3237 if((eRet == OMX_ErrorNone) &&
3238 (BITMASK_PRESENT(&m_flags ,OMX_COMPONENT_LOADING_PENDING)))
3239 {
3240 if(release_done())
3241 {
3242 if(dev_stop() != 0)
3243 {
3244 DEBUG_PRINT_ERROR("ERROR: dev_stop() FAILED\n");
3245 eRet = OMX_ErrorHardware;
3246 }
3247 // Send the callback now
3248 BITMASK_CLEAR((&m_flags),OMX_COMPONENT_LOADING_PENDING);
3249 post_event(OMX_CommandStateSet, OMX_StateLoaded,
3250 OMX_COMPONENT_GENERATE_EVENT);
3251 }
3252 }
3253
3254 return eRet;
3255 }
3256
3257
3258 /* ======================================================================
3259 FUNCTION
3260 omx_video::EmptyThisBuffer
3261
3262 DESCRIPTION
3263 This routine is used to push the encoded video frames to
3264 the video decoder.
3265
3266 PARAMETERS
3267 None.
3268
3269 RETURN VALUE
3270 OMX Error None if everything went successful.
3271
3272 ========================================================================== */
empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3273 OMX_ERRORTYPE omx_video::empty_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
3274 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3275 {
3276 OMX_ERRORTYPE ret1 = OMX_ErrorNone;
3277 unsigned int nBufferIndex ;
3278
3279 DEBUG_PRINT_LOW("\n ETB: buffer = %p, buffer->pBuffer[%p]\n", buffer, buffer->pBuffer);
3280 if(m_state == OMX_StateInvalid)
3281 {
3282 DEBUG_PRINT_ERROR("ERROR: Empty this buffer in Invalid State\n");
3283 return OMX_ErrorInvalidState;
3284 }
3285
3286 if (buffer == NULL || (buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
3287 {
3288 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> buffer is null or buffer size is invalid");
3289 return OMX_ErrorBadParameter;
3290 }
3291
3292 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
3293 {
3294 DEBUG_PRINT_ERROR("\nERROR: omx_video::etb--> OMX Version Invalid");
3295 return OMX_ErrorVersionMismatch;
3296 }
3297
3298 if (buffer->nInputPortIndex != (OMX_U32)PORT_INDEX_IN)
3299 {
3300 DEBUG_PRINT_ERROR("\nERROR: Bad port index to call empty_this_buffer");
3301 return OMX_ErrorBadPortIndex;
3302 }
3303 if(!m_sInPortDef.bEnabled)
3304 {
3305 DEBUG_PRINT_ERROR("\nERROR: Cannot call empty_this_buffer while I/P port is disabled");
3306 return OMX_ErrorIncorrectStateOperation;
3307 }
3308
3309 nBufferIndex = buffer - ((!mUseProxyColorFormat)?m_inp_mem_ptr:meta_buffer_hdr);
3310
3311 if(nBufferIndex > m_sInPortDef.nBufferCountActual )
3312 {
3313 DEBUG_PRINT_ERROR("ERROR: ETB: Invalid buffer index[%d]\n", nBufferIndex);
3314 return OMX_ErrorBadParameter;
3315 }
3316
3317 m_etb_count++;
3318 DEBUG_PRINT_LOW("\n DBG: i/p nTimestamp = %u", (unsigned)buffer->nTimeStamp);
3319 post_event ((unsigned)hComp,(unsigned)buffer,m_input_msg_id);
3320 return OMX_ErrorNone;
3321 }
3322 /* ======================================================================
3323 FUNCTION
3324 omx_video::empty_this_buffer_proxy
3325
3326 DESCRIPTION
3327 This routine is used to push the encoded video frames to
3328 the video decoder.
3329
3330 PARAMETERS
3331 None.
3332
3333 RETURN VALUE
3334 OMX Error None if everything went successful.
3335
3336 ========================================================================== */
empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3337 OMX_ERRORTYPE omx_video::empty_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,
3338 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3339 {
3340 OMX_U8 *pmem_data_buf = NULL;
3341 int push_cnt = 0;
3342 unsigned nBufIndex = 0,nBufIndex_meta = 0;
3343 OMX_ERRORTYPE ret = OMX_ErrorNone;
3344
3345 DEBUG_PRINT_LOW("\n ETBProxy: buffer[%p]\n", buffer);
3346
3347 if(buffer == NULL)
3348 {
3349 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid buffer[%p]\n", buffer);
3350 return OMX_ErrorBadParameter;
3351 }
3352
3353 nBufIndex = buffer - ((OMX_BUFFERHEADERTYPE *)m_inp_mem_ptr);
3354 nBufIndex_meta = buffer - meta_buffer_hdr;
3355 if(nBufIndex >= m_sInPortDef.nBufferCountActual &&
3356 nBufIndex_meta >= m_sInPortDef.nBufferCountActual)
3357 {
3358 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Invalid bufindex = %u\n", nBufIndex);
3359 return OMX_ErrorBadParameter;
3360 }
3361
3362 pending_input_buffers++;
3363 if(input_flush_progress == true)
3364 {
3365 post_event ((unsigned int)buffer,0,
3366 OMX_COMPONENT_GENERATE_EBD);
3367 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Input flush in progress");
3368 return OMX_ErrorNone;
3369 }
3370 #ifdef _ANDROID_ICS_
3371 if(meta_mode_enable && !mUseProxyColorFormat)
3372 {
3373 encoder_media_buffer_type *media_buffer;
3374 bool met_error = false;
3375 media_buffer = (encoder_media_buffer_type *)meta_buffer_hdr[nBufIndex].pBuffer;
3376 if(media_buffer)
3377 {
3378 if (media_buffer->buffer_type != kMetadataBufferTypeCameraSource &&
3379 media_buffer->buffer_type != kMetadataBufferTypeGrallocSource) {
3380 met_error = true;
3381 } else {
3382 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
3383 {
3384 if(media_buffer->meta_handle == NULL) {
3385 met_error = true;
3386 }
3387 else if((media_buffer->meta_handle->numFds != 1 &&
3388 media_buffer->meta_handle->numInts != 2))
3389 {
3390 met_error = true;
3391 }
3392 }
3393 }
3394 } else {
3395 met_error = true;
3396 }
3397 if(met_error)
3398 {
3399 DEBUG_PRINT_ERROR("\nERROR: Unkown source/metahandle in ETB call");
3400 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3401 return OMX_ErrorBadParameter;
3402 }
3403
3404 struct pmem Input_pmem_info;
3405 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource)
3406 {
3407 Input_pmem_info.buffer = media_buffer;
3408 Input_pmem_info.fd = media_buffer->meta_handle->data[0];
3409 Input_pmem_info.offset = media_buffer->meta_handle->data[1];
3410 Input_pmem_info.size = media_buffer->meta_handle->data[2];
3411 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
3412 Input_pmem_info.offset,
3413 Input_pmem_info.size);
3414
3415 } else {
3416 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
3417 if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
3418 DEBUG_PRINT_ERROR("\n Incorrect pixel format");
3419 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3420 return OMX_ErrorBadParameter;
3421 }
3422 Input_pmem_info.buffer = media_buffer;
3423 Input_pmem_info.fd = handle->fd;
3424 Input_pmem_info.offset = 0;
3425 Input_pmem_info.size = handle->size;
3426 }
3427 if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
3428 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
3429 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3430 return OMX_ErrorBadParameter;
3431 }
3432 }
3433 else if(input_use_buffer && !m_use_input_pmem)
3434 #else
3435 if(input_use_buffer && !m_use_input_pmem)
3436 #endif
3437 {
3438 DEBUG_PRINT_LOW("\n Heap UseBuffer case, so memcpy the data");
3439 pmem_data_buf = (OMX_U8 *)m_pInput_pmem[nBufIndex].buffer;
3440
3441 memcpy (pmem_data_buf, (buffer->pBuffer + buffer->nOffset),
3442 buffer->nFilledLen);
3443 DEBUG_PRINT_LOW("memcpy() done in ETBProxy for i/p Heap UseBuf");
3444 } else if (m_sInPortDef.format.video.eColorFormat ==
3445 OMX_COLOR_FormatYUV420SemiPlanar && !mUseProxyColorFormat) {
3446 //For the case where YUV420SP buffers are qeueued to component
3447 //by sources other than camera (Apps via MediaCodec), alignment
3448 //of chroma-plane to 2K is necessary.
3449 //For RGB buffers, color-conversion takes care of such alignment
3450 OMX_U32 width = m_sInPortDef.format.video.nFrameWidth;
3451 OMX_U32 height = m_sInPortDef.format.video.nFrameHeight;
3452 OMX_U32 chromaOffset = width * height;
3453 if (IS_NOT_ALIGNED(chromaOffset, SZ_2K)) {
3454 OMX_U32 chromaSize = (width * height)/2;
3455 chromaOffset = ALIGN(chromaOffset,SZ_2K);
3456 if (buffer->nAllocLen >= chromaOffset + chromaSize) {
3457 OMX_U8* buf = buffer->pBuffer;
3458 memmove(buf + chromaOffset, buf + (width*height), chromaSize);
3459 } else {
3460 DEBUG_PRINT_ERROR("Failed to align Chroma. from %u to %u : \
3461 Insufficient bufferLen=%u v/s Required=%u",
3462 (width*height), chromaOffset, buffer->nAllocLen,
3463 chromaOffset+chromaSize);
3464 }
3465 }
3466 }
3467 #ifdef _COPPER_
3468 if(dev_empty_buf(buffer, pmem_data_buf,nBufIndex,m_pInput_pmem[nBufIndex].fd) != true)
3469 #else
3470 if(dev_empty_buf(buffer, pmem_data_buf,0,0) != true)
3471 #endif
3472 {
3473 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: dev_empty_buf failed");
3474 #ifdef _ANDROID_ICS_
3475 omx_release_meta_buffer(buffer);
3476 #endif
3477 post_event ((unsigned int)buffer,0,OMX_COMPONENT_GENERATE_EBD);
3478 /*Generate an async error and move to invalid state*/
3479 pending_input_buffers--;
3480 return OMX_ErrorBadParameter;
3481 }
3482
3483 return ret;
3484 }
3485
3486 /* ======================================================================
3487 FUNCTION
3488 omx_video::FillThisBuffer
3489
3490 DESCRIPTION
3491 IL client uses this method to release the frame buffer
3492 after displaying them.
3493
3494 PARAMETERS
3495 None.
3496
3497 RETURN VALUE
3498 true/false
3499
3500 ========================================================================== */
fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)3501 OMX_ERRORTYPE omx_video::fill_this_buffer(OMX_IN OMX_HANDLETYPE hComp,
3502 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
3503 {
3504 DEBUG_PRINT_LOW("\n FTB: buffer->pBuffer[%p]\n", buffer->pBuffer);
3505 if(m_state == OMX_StateInvalid)
3506 {
3507 DEBUG_PRINT_ERROR("ERROR: FTB in Invalid State\n");
3508 return OMX_ErrorInvalidState;
3509 }
3510
3511 if (buffer == NULL ||(buffer->nSize != sizeof(OMX_BUFFERHEADERTYPE)))
3512 {
3513 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Invalid buffer or size\n");
3514 return OMX_ErrorBadParameter;
3515 }
3516
3517 if(buffer->nVersion.nVersion != OMX_SPEC_VERSION)
3518 {
3519 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->OMX Version Invalid\n");
3520 return OMX_ErrorVersionMismatch;
3521 }
3522
3523 if (buffer->nOutputPortIndex != (OMX_U32)PORT_INDEX_OUT)
3524 {
3525 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->Bad port index\n");
3526 return OMX_ErrorBadPortIndex;
3527 }
3528
3529 if(!m_sOutPortDef.bEnabled)
3530 {
3531 DEBUG_PRINT_ERROR("ERROR: omx_video::ftb-->port is disabled\n");
3532 return OMX_ErrorIncorrectStateOperation;
3533 }
3534
3535 post_event((unsigned) hComp, (unsigned)buffer,OMX_COMPONENT_GENERATE_FTB);
3536 return OMX_ErrorNone;
3537 }
3538
3539 /* ======================================================================
3540 FUNCTION
3541 omx_video::fill_this_buffer_proxy
3542
3543 DESCRIPTION
3544 IL client uses this method to release the frame buffer
3545 after displaying them.
3546
3547 PARAMETERS
3548 None.
3549
3550 RETURN VALUE
3551 true/false
3552
3553 ========================================================================== */
fill_this_buffer_proxy(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * bufferAdd)3554 OMX_ERRORTYPE omx_video::fill_this_buffer_proxy(
3555 OMX_IN OMX_HANDLETYPE hComp,
3556 OMX_IN OMX_BUFFERHEADERTYPE* bufferAdd)
3557 {
3558 OMX_U8 *pmem_data_buf = NULL;
3559 OMX_ERRORTYPE nRet = OMX_ErrorNone;
3560
3561 DEBUG_PRINT_LOW("\n FTBProxy: bufferAdd->pBuffer[%p]\n", bufferAdd->pBuffer);
3562
3563 if(bufferAdd == NULL || ((bufferAdd - m_out_mem_ptr) >= m_sOutPortDef.nBufferCountActual) )
3564 {
3565 DEBUG_PRINT_ERROR("\nERROR: FTBProxy: Invalid i/p params\n");
3566 return OMX_ErrorBadParameter;
3567 }
3568
3569 pending_output_buffers++;
3570 /*Return back the output buffer to client*/
3571 if( m_sOutPortDef.bEnabled != OMX_TRUE || output_flush_progress == true)
3572 {
3573 DEBUG_PRINT_LOW("\n o/p port is Disabled or Flush in Progress");
3574 post_event ((unsigned int)bufferAdd,0,
3575 OMX_COMPONENT_GENERATE_FBD);
3576 return OMX_ErrorNone;
3577 }
3578
3579 if(output_use_buffer && !m_use_output_pmem)
3580 {
3581 DEBUG_PRINT_LOW("\n Heap UseBuffer case");
3582 pmem_data_buf = (OMX_U8 *)m_pOutput_pmem[bufferAdd - m_out_mem_ptr].buffer;
3583 }
3584
3585 if(dev_fill_buf(bufferAdd, pmem_data_buf,(bufferAdd - m_out_mem_ptr),m_pOutput_pmem[bufferAdd - m_out_mem_ptr].fd) != true)
3586 {
3587 DEBUG_PRINT_ERROR("\nERROR: dev_fill_buf() Failed");
3588 post_event ((unsigned int)bufferAdd,0,OMX_COMPONENT_GENERATE_FBD);
3589 pending_output_buffers--;
3590 return OMX_ErrorBadParameter;
3591 }
3592
3593 return OMX_ErrorNone;
3594 }
3595
3596 /* ======================================================================
3597 FUNCTION
3598 omx_video::SetCallbacks
3599
3600 DESCRIPTION
3601 Set the callbacks.
3602
3603 PARAMETERS
3604 None.
3605
3606 RETURN VALUE
3607 OMX Error None if everything successful.
3608
3609 ========================================================================== */
set_callbacks(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_CALLBACKTYPE * callbacks,OMX_IN OMX_PTR appData)3610 OMX_ERRORTYPE omx_video::set_callbacks(OMX_IN OMX_HANDLETYPE hComp,
3611 OMX_IN OMX_CALLBACKTYPE* callbacks,
3612 OMX_IN OMX_PTR appData)
3613 {
3614
3615 m_pCallbacks = *callbacks;
3616 DEBUG_PRINT_LOW("\n Callbacks Set %p %p %p",m_pCallbacks.EmptyBufferDone,\
3617 m_pCallbacks.EventHandler,m_pCallbacks.FillBufferDone);
3618 m_app_data = appData;
3619 return OMX_ErrorNotImplemented;
3620 }
3621
3622
3623 /* ======================================================================
3624 FUNCTION
3625 omx_venc::UseEGLImage
3626
3627 DESCRIPTION
3628 OMX Use EGL Image method implementation <TBD>.
3629
3630 PARAMETERS
3631 <TBD>.
3632
3633 RETURN VALUE
3634 Not Implemented error.
3635
3636 ========================================================================== */
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)3637 OMX_ERRORTYPE omx_video::use_EGL_image(OMX_IN OMX_HANDLETYPE hComp,
3638 OMX_INOUT OMX_BUFFERHEADERTYPE** bufferHdr,
3639 OMX_IN OMX_U32 port,
3640 OMX_IN OMX_PTR appData,
3641 OMX_IN void* eglImage)
3642 {
3643 DEBUG_PRINT_ERROR("ERROR: use_EGL_image: Not Implemented \n");
3644 return OMX_ErrorNotImplemented;
3645 }
3646
3647 /* ======================================================================
3648 FUNCTION
3649 omx_venc::ComponentRoleEnum
3650
3651 DESCRIPTION
3652 OMX Component Role Enum method implementation.
3653
3654 PARAMETERS
3655 <TBD>.
3656
3657 RETURN VALUE
3658 OMX Error None if everything is successful.
3659 ========================================================================== */
component_role_enum(OMX_IN OMX_HANDLETYPE hComp,OMX_OUT OMX_U8 * role,OMX_IN OMX_U32 index)3660 OMX_ERRORTYPE omx_video::component_role_enum(OMX_IN OMX_HANDLETYPE hComp,
3661 OMX_OUT OMX_U8* role,
3662 OMX_IN OMX_U32 index)
3663 {
3664 OMX_ERRORTYPE eRet = OMX_ErrorNone;
3665 if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3666 {
3667 if((0 == index) && role)
3668 {
3669 strlcpy((char *)role, "video_decoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3670 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3671 }
3672 else
3673 {
3674 eRet = OMX_ErrorNoMore;
3675 }
3676 }
3677 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.h263",OMX_MAX_STRINGNAME_SIZE))
3678 {
3679 if((0 == index) && role)
3680 {
3681 strlcpy((char *)role, "video_decoder.h263",OMX_MAX_STRINGNAME_SIZE);
3682 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3683 }
3684 else
3685 {
3686 DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3687 eRet = OMX_ErrorNoMore;
3688 }
3689 }
3690 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.avc",OMX_MAX_STRINGNAME_SIZE))
3691 {
3692 if((0 == index) && role)
3693 {
3694 strlcpy((char *)role, "video_decoder.avc",OMX_MAX_STRINGNAME_SIZE);
3695 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3696 }
3697 else
3698 {
3699 DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3700 eRet = OMX_ErrorNoMore;
3701 }
3702 }
3703 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.decoder.vc1",OMX_MAX_STRINGNAME_SIZE))
3704 {
3705 if((0 == index) && role)
3706 {
3707 strlcpy((char *)role, "video_decoder.vc1",OMX_MAX_STRINGNAME_SIZE);
3708 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3709 }
3710 else
3711 {
3712 DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3713 eRet = OMX_ErrorNoMore;
3714 }
3715 }
3716 if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE))
3717 {
3718 if((0 == index) && role)
3719 {
3720 strlcpy((char *)role, "video_encoder.mpeg4",OMX_MAX_STRINGNAME_SIZE);
3721 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3722 }
3723 else
3724 {
3725 eRet = OMX_ErrorNoMore;
3726 }
3727 }
3728 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.h263",OMX_MAX_STRINGNAME_SIZE))
3729 {
3730 if((0 == index) && role)
3731 {
3732 strlcpy((char *)role, "video_encoder.h263",OMX_MAX_STRINGNAME_SIZE);
3733 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3734 }
3735 else
3736 {
3737 DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3738 eRet = OMX_ErrorNoMore;
3739 }
3740 }
3741 else if(!strncmp((char*)m_nkind, "OMX.qcom.video.encoder.avc",OMX_MAX_STRINGNAME_SIZE))
3742 {
3743 if((0 == index) && role)
3744 {
3745 strlcpy((char *)role, "video_encoder.avc",OMX_MAX_STRINGNAME_SIZE);
3746 DEBUG_PRINT_LOW("component_role_enum: role %s\n",role);
3747 }
3748 else
3749 {
3750 DEBUG_PRINT_ERROR("\nERROR: No more roles \n");
3751 eRet = OMX_ErrorNoMore;
3752 }
3753 }
3754 else
3755 {
3756 DEBUG_PRINT_ERROR("\nERROR: Querying Role on Unknown Component\n");
3757 eRet = OMX_ErrorInvalidComponentName;
3758 }
3759 return eRet;
3760 }
3761
3762
3763
3764
3765 /* ======================================================================
3766 FUNCTION
3767 omx_venc::AllocateDone
3768
3769 DESCRIPTION
3770 Checks if entire buffer pool is allocated by IL Client or not.
3771 Need this to move to IDLE state.
3772
3773 PARAMETERS
3774 None.
3775
3776 RETURN VALUE
3777 true/false.
3778
3779 ========================================================================== */
allocate_done(void)3780 bool omx_video::allocate_done(void)
3781 {
3782 bool bRet = false;
3783 bool bRet_In = false;
3784 bool bRet_Out = false;
3785
3786 bRet_In = allocate_input_done();
3787 bRet_Out = allocate_output_done();
3788
3789 if(bRet_In && bRet_Out)
3790 {
3791 bRet = true;
3792 }
3793
3794 return bRet;
3795 }
3796 /* ======================================================================
3797 FUNCTION
3798 omx_venc::AllocateInputDone
3799
3800 DESCRIPTION
3801 Checks if I/P buffer pool is allocated by IL Client or not.
3802
3803 PARAMETERS
3804 None.
3805
3806 RETURN VALUE
3807 true/false.
3808
3809 ========================================================================== */
allocate_input_done(void)3810 bool omx_video::allocate_input_done(void)
3811 {
3812 bool bRet = false;
3813 unsigned i=0;
3814
3815 if(m_inp_mem_ptr == NULL)
3816 {
3817 return bRet;
3818 }
3819 if(m_inp_mem_ptr )
3820 {
3821 for(;i<m_sInPortDef.nBufferCountActual;i++)
3822 {
3823 if(BITMASK_ABSENT(&m_inp_bm_count,i))
3824 {
3825 break;
3826 }
3827 }
3828 }
3829 if(i==m_sInPortDef.nBufferCountActual)
3830 {
3831 bRet = true;
3832 }
3833 if(i==m_sInPortDef.nBufferCountActual && m_sInPortDef.bEnabled)
3834 {
3835 m_sInPortDef.bPopulated = OMX_TRUE;
3836 }
3837 return bRet;
3838 }
3839 /* ======================================================================
3840 FUNCTION
3841 omx_venc::AllocateOutputDone
3842
3843 DESCRIPTION
3844 Checks if entire O/P buffer pool is allocated by IL Client or not.
3845
3846 PARAMETERS
3847 None.
3848
3849 RETURN VALUE
3850 true/false.
3851
3852 ========================================================================== */
allocate_output_done(void)3853 bool omx_video::allocate_output_done(void)
3854 {
3855 bool bRet = false;
3856 unsigned j=0;
3857
3858 if(m_out_mem_ptr == NULL)
3859 {
3860 return bRet;
3861 }
3862
3863 if(m_out_mem_ptr )
3864 {
3865 for(;j<m_sOutPortDef.nBufferCountActual;j++)
3866 {
3867 if(BITMASK_ABSENT(&m_out_bm_count,j))
3868 {
3869 break;
3870 }
3871 }
3872 }
3873
3874 if(j==m_sOutPortDef.nBufferCountActual)
3875 {
3876 bRet = true;
3877 }
3878
3879 if(j==m_sOutPortDef.nBufferCountActual && m_sOutPortDef.bEnabled)
3880 {
3881 m_sOutPortDef.bPopulated = OMX_TRUE;
3882 }
3883 return bRet;
3884 }
3885
3886 /* ======================================================================
3887 FUNCTION
3888 omx_venc::ReleaseDone
3889
3890 DESCRIPTION
3891 Checks if IL client has released all the buffers.
3892
3893 PARAMETERS
3894 None.
3895
3896 RETURN VALUE
3897 true/false
3898
3899 ========================================================================== */
release_done(void)3900 bool omx_video::release_done(void)
3901 {
3902 bool bRet = false;
3903 DEBUG_PRINT_LOW("Inside release_done()\n");
3904 if(release_input_done())
3905 {
3906 if(release_output_done())
3907 {
3908 bRet = true;
3909 }
3910 }
3911 return bRet;
3912 }
3913
3914
3915 /* ======================================================================
3916 FUNCTION
3917 omx_venc::ReleaseOutputDone
3918
3919 DESCRIPTION
3920 Checks if IL client has released all the buffers.
3921
3922 PARAMETERS
3923 None.
3924
3925 RETURN VALUE
3926 true/false
3927
3928 ========================================================================== */
release_output_done(void)3929 bool omx_video::release_output_done(void)
3930 {
3931 bool bRet = false;
3932 unsigned i=0,j=0;
3933
3934 DEBUG_PRINT_LOW("Inside release_output_done()\n");
3935 if(m_out_mem_ptr)
3936 {
3937 for(;j<m_sOutPortDef.nBufferCountActual;j++)
3938 {
3939 if(BITMASK_PRESENT(&m_out_bm_count,j))
3940 {
3941 break;
3942 }
3943 }
3944 if(j==m_sOutPortDef.nBufferCountActual)
3945 {
3946 bRet = true;
3947 }
3948 }
3949 else
3950 {
3951 bRet = true;
3952 }
3953 return bRet;
3954 }
3955 /* ======================================================================
3956 FUNCTION
3957 omx_venc::ReleaseInputDone
3958
3959 DESCRIPTION
3960 Checks if IL client has released all the buffers.
3961
3962 PARAMETERS
3963 None.
3964
3965 RETURN VALUE
3966 true/false
3967
3968 ========================================================================== */
release_input_done(void)3969 bool omx_video::release_input_done(void)
3970 {
3971 bool bRet = false;
3972 unsigned i=0,j=0;
3973
3974 DEBUG_PRINT_LOW("Inside release_input_done()\n");
3975 if(m_inp_mem_ptr)
3976 {
3977 for(;j<m_sInPortDef.nBufferCountActual;j++)
3978 {
3979 if( BITMASK_PRESENT(&m_inp_bm_count,j))
3980 {
3981 break;
3982 }
3983 }
3984 if(j==m_sInPortDef.nBufferCountActual)
3985 {
3986 bRet = true;
3987 }
3988 }
3989 else
3990 {
3991 bRet = true;
3992 }
3993 return bRet;
3994 }
3995
fill_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)3996 OMX_ERRORTYPE omx_video::fill_buffer_done(OMX_HANDLETYPE hComp,
3997 OMX_BUFFERHEADERTYPE * buffer)
3998 {
3999 DEBUG_PRINT_LOW("fill_buffer_done: buffer->pBuffer[%p], flags=0x%x size = %d",
4000 buffer->pBuffer, buffer->nFlags,buffer->nFilledLen);
4001 if(buffer == NULL || ((buffer - m_out_mem_ptr) > m_sOutPortDef.nBufferCountActual))
4002 {
4003 return OMX_ErrorBadParameter;
4004 }
4005
4006 pending_output_buffers--;
4007 if(!secure_session)
4008 {
4009 extra_data_handle.create_extra_data(buffer);
4010 }
4011
4012 if (!secure_session && m_sDebugSliceinfo) {
4013 if(buffer->nFlags & OMX_BUFFERFLAG_EXTRADATA) {
4014 DEBUG_PRINT_HIGH("parsing extradata");
4015 extra_data_handle.parse_extra_data(buffer);
4016 }
4017 }
4018 /* For use buffer we need to copy the data */
4019 if(m_pCallbacks.FillBufferDone)
4020 {
4021 if(buffer->nFilledLen > 0)
4022 {
4023 m_fbd_count++;
4024
4025 #ifdef OUTPUT_BUFFER_LOG
4026 if(outputBufferFile1)
4027 {
4028 fwrite((const char *)buffer->pBuffer, buffer->nFilledLen, 1, outputBufferFile1);
4029 }
4030 #endif
4031 }
4032 m_pCallbacks.FillBufferDone (hComp,m_app_data,buffer);
4033 }
4034 else
4035 {
4036 return OMX_ErrorBadParameter;
4037 }
4038 return OMX_ErrorNone;
4039 }
4040
empty_buffer_done(OMX_HANDLETYPE hComp,OMX_BUFFERHEADERTYPE * buffer)4041 OMX_ERRORTYPE omx_video::empty_buffer_done(OMX_HANDLETYPE hComp,
4042 OMX_BUFFERHEADERTYPE* buffer)
4043 {
4044 int buffer_index = -1;
4045 int buffer_index_meta = -1;
4046
4047 buffer_index = (buffer - m_inp_mem_ptr);
4048 buffer_index_meta = (buffer - meta_buffer_hdr);
4049 DEBUG_PRINT_LOW("\n empty_buffer_done: buffer[%p]", buffer);
4050 if(buffer == NULL ||
4051 ((buffer_index > m_sInPortDef.nBufferCountActual) &&
4052 (buffer_index_meta > m_sInPortDef.nBufferCountActual)))
4053 {
4054 DEBUG_PRINT_ERROR("\n ERROR in empty_buffer_done due to index buffer");
4055 return OMX_ErrorBadParameter;
4056 }
4057
4058 pending_input_buffers--;
4059
4060 if(mUseProxyColorFormat && ((OMX_U32)buffer_index < m_sInPortDef.nBufferCountActual)) {
4061 if(!pdest_frame) {
4062 pdest_frame = buffer;
4063 DEBUG_PRINT_LOW("\n empty_buffer_done pdest_frame address is %p",pdest_frame);
4064 return push_input_buffer(hComp);
4065
4066 } else {
4067 DEBUG_PRINT_LOW("\n empty_buffer_done insert address is %p",buffer);
4068 if (!m_opq_pmem_q.insert_entry((unsigned int)buffer, 0, 0)) {
4069 DEBUG_PRINT_ERROR("\n empty_buffer_done: pmem queue is full");
4070 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4071 return OMX_ErrorBadParameter;
4072 }
4073 }
4074 } else if(m_pCallbacks.EmptyBufferDone) {
4075 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, buffer);
4076 }
4077 return OMX_ErrorNone;
4078 }
4079
complete_pending_buffer_done_cbs()4080 void omx_video::complete_pending_buffer_done_cbs()
4081 {
4082 unsigned p1;
4083 unsigned p2;
4084 unsigned ident;
4085 omx_cmd_queue tmp_q, pending_bd_q;
4086 pthread_mutex_lock(&m_lock);
4087 // pop all pending GENERATE FDB from ftb queue
4088 while (m_ftb_q.m_size)
4089 {
4090 m_ftb_q.pop_entry(&p1,&p2,&ident);
4091 if(ident == OMX_COMPONENT_GENERATE_FBD)
4092 {
4093 pending_bd_q.insert_entry(p1,p2,ident);
4094 }
4095 else
4096 {
4097 tmp_q.insert_entry(p1,p2,ident);
4098 }
4099 }
4100 //return all non GENERATE FDB to ftb queue
4101 while(tmp_q.m_size)
4102 {
4103 tmp_q.pop_entry(&p1,&p2,&ident);
4104 m_ftb_q.insert_entry(p1,p2,ident);
4105 }
4106 // pop all pending GENERATE EDB from etb queue
4107 while (m_etb_q.m_size)
4108 {
4109 m_etb_q.pop_entry(&p1,&p2,&ident);
4110 if(ident == OMX_COMPONENT_GENERATE_EBD)
4111 {
4112 pending_bd_q.insert_entry(p1,p2,ident);
4113 }
4114 else
4115 {
4116 tmp_q.insert_entry(p1,p2,ident);
4117 }
4118 }
4119 //return all non GENERATE FDB to etb queue
4120 while(tmp_q.m_size)
4121 {
4122 tmp_q.pop_entry(&p1,&p2,&ident);
4123 m_etb_q.insert_entry(p1,p2,ident);
4124 }
4125 pthread_mutex_unlock(&m_lock);
4126 // process all pending buffer dones
4127 while(pending_bd_q.m_size)
4128 {
4129 pending_bd_q.pop_entry(&p1,&p2,&ident);
4130 switch(ident)
4131 {
4132 case OMX_COMPONENT_GENERATE_EBD:
4133 if(empty_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone)
4134 {
4135 DEBUG_PRINT_ERROR("\nERROR: empty_buffer_done() failed!\n");
4136 omx_report_error ();
4137 }
4138 break;
4139
4140 case OMX_COMPONENT_GENERATE_FBD:
4141 if(fill_buffer_done(&m_cmp, (OMX_BUFFERHEADERTYPE *)p1) != OMX_ErrorNone )
4142 {
4143 DEBUG_PRINT_ERROR("\nERROR: fill_buffer_done() failed!\n");
4144 omx_report_error ();
4145 }
4146 break;
4147 }
4148 }
4149 }
4150
4151 #ifdef MAX_RES_720P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4152 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4153 {
4154 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4155 if(!profileLevelType)
4156 return OMX_ErrorBadParameter;
4157
4158 if(profileLevelType->nPortIndex == 1) {
4159 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4160 {
4161 if (profileLevelType->nProfileIndex == 0)
4162 {
4163 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4164 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
4165 }
4166 else if (profileLevelType->nProfileIndex == 1)
4167 {
4168 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4169 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
4170 }
4171 else if(profileLevelType->nProfileIndex == 2)
4172 {
4173 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4174 profileLevelType->eLevel = OMX_VIDEO_AVCLevel31;
4175 }
4176 else
4177 {
4178 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4179 profileLevelType->nProfileIndex);
4180 eRet = OMX_ErrorNoMore;
4181 }
4182 }
4183 else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4184 {
4185 if (profileLevelType->nProfileIndex == 0)
4186 {
4187 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4188 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
4189 }
4190 else
4191 {
4192 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4193 eRet = OMX_ErrorNoMore;
4194 }
4195 }
4196 else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4197 {
4198 if (profileLevelType->nProfileIndex == 0)
4199 {
4200 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4201 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
4202 }
4203 else if(profileLevelType->nProfileIndex == 1)
4204 {
4205 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4206 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
4207 }
4208 else
4209 {
4210 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4211 eRet = OMX_ErrorNoMore;
4212 }
4213 }
4214 }
4215 else
4216 {
4217 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4218 eRet = OMX_ErrorBadPortIndex;
4219 }
4220 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4221 profileLevelType->eProfile,profileLevelType->eLevel);
4222 return eRet;
4223 }
4224 #endif
4225
4226 #ifdef MAX_RES_1080P
get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE * profileLevelType)4227 OMX_ERRORTYPE omx_video::get_supported_profile_level(OMX_VIDEO_PARAM_PROFILELEVELTYPE *profileLevelType)
4228 {
4229 OMX_ERRORTYPE eRet = OMX_ErrorNone;
4230 if(!profileLevelType)
4231 return OMX_ErrorBadParameter;
4232
4233 if(profileLevelType->nPortIndex == 1) {
4234 if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingAVC)
4235 {
4236 if (profileLevelType->nProfileIndex == 0)
4237 {
4238 profileLevelType->eProfile = OMX_VIDEO_AVCProfileBaseline;
4239 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
4240
4241 }
4242 else if (profileLevelType->nProfileIndex == 1)
4243 {
4244 profileLevelType->eProfile = OMX_VIDEO_AVCProfileMain;
4245 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
4246 }
4247 else if(profileLevelType->nProfileIndex == 2)
4248 {
4249 profileLevelType->eProfile = OMX_VIDEO_AVCProfileHigh;
4250 profileLevelType->eLevel = OMX_VIDEO_AVCLevel4;
4251 }
4252 else
4253 {
4254 DEBUG_PRINT_LOW("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n",
4255 profileLevelType->nProfileIndex);
4256 eRet = OMX_ErrorNoMore;
4257 }
4258 }
4259 else if (m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingH263)
4260 {
4261 if (profileLevelType->nProfileIndex == 0)
4262 {
4263 profileLevelType->eProfile = OMX_VIDEO_H263ProfileBaseline;
4264 profileLevelType->eLevel = OMX_VIDEO_H263Level70;
4265 }
4266 else
4267 {
4268 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4269 eRet = OMX_ErrorNoMore;
4270 }
4271 }
4272 else if(m_sOutPortDef.format.video.eCompressionFormat == OMX_VIDEO_CodingMPEG4)
4273 {
4274 if (profileLevelType->nProfileIndex == 0)
4275 {
4276 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileSimple;
4277 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
4278 }
4279 else if(profileLevelType->nProfileIndex == 1)
4280 {
4281 profileLevelType->eProfile = OMX_VIDEO_MPEG4ProfileAdvancedSimple;
4282 profileLevelType->eLevel = OMX_VIDEO_MPEG4Level5;
4283 }
4284 else
4285 {
4286 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported nProfileIndex ret NoMore %d\n", profileLevelType->nProfileIndex);
4287 eRet = OMX_ErrorNoMore;
4288 }
4289 }
4290 }
4291 else
4292 {
4293 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported should be queries on Input port only %d\n", profileLevelType->nPortIndex);
4294 eRet = OMX_ErrorBadPortIndex;
4295 }
4296 DEBUG_PRINT_ERROR("get_parameter: OMX_IndexParamVideoProfileLevelQuerySupported for Input port returned Profile:%d, Level:%d\n",
4297 profileLevelType->eProfile,profileLevelType->eLevel);
4298 return eRet;
4299 }
4300
4301 #ifdef USE_ION
alloc_map_ion_memory(int size,struct ion_allocation_data * alloc_data,struct ion_fd_data * fd_data,int flag)4302 int omx_video::alloc_map_ion_memory(int size,struct ion_allocation_data *alloc_data,
4303 struct ion_fd_data *fd_data,int flag)
4304 {
4305 struct venc_ion buf_ion_info;
4306 int ion_device_fd =-1,rc=0,ion_dev_flags = 0;
4307 if (size <=0 || !alloc_data || !fd_data) {
4308 DEBUG_PRINT_ERROR("\nInvalid input to alloc_map_ion_memory");
4309 return -EINVAL;
4310 }
4311 ion_dev_flags = O_RDONLY;
4312 ion_device_fd = open (MEM_DEVICE,ion_dev_flags);
4313 if(ion_device_fd < 0)
4314 {
4315 DEBUG_PRINT_ERROR("\nERROR: ION Device open() Failed");
4316 return ion_device_fd;
4317 }
4318 alloc_data->len = size;
4319 alloc_data->align = 4096;
4320 alloc_data->flags = 0;
4321 if(!secure_session && (flag & ION_FLAG_CACHED))
4322 {
4323 alloc_data->flags = ION_FLAG_CACHED;
4324 }
4325
4326 if (secure_session)
4327 alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) | ION_SECURE);
4328 else
4329 alloc_data->heap_id_mask = (ION_HEAP(MEM_HEAP_ID) |
4330 ION_HEAP(ION_IOMMU_HEAP_ID));
4331
4332 rc = ioctl(ion_device_fd,ION_IOC_ALLOC,alloc_data);
4333 if(rc || !alloc_data->handle) {
4334 DEBUG_PRINT_ERROR("\n ION ALLOC memory failed ");
4335 alloc_data->handle =NULL;
4336 close(ion_device_fd);
4337 ion_device_fd = -1;
4338 return ion_device_fd;
4339 }
4340 fd_data->handle = alloc_data->handle;
4341 rc = ioctl(ion_device_fd,ION_IOC_MAP,fd_data);
4342 if(rc) {
4343 DEBUG_PRINT_ERROR("\n ION MAP failed ");
4344 buf_ion_info.ion_alloc_data = *alloc_data;
4345 buf_ion_info.ion_device_fd = ion_device_fd;
4346 buf_ion_info.fd_ion_data = *fd_data;
4347 free_ion_memory(&buf_ion_info);
4348 fd_data->fd =-1;
4349 ion_device_fd =-1;
4350 }
4351 return ion_device_fd;
4352 }
4353
free_ion_memory(struct venc_ion * buf_ion_info)4354 void omx_video::free_ion_memory(struct venc_ion *buf_ion_info)
4355 {
4356 if (!buf_ion_info) {
4357 DEBUG_PRINT_ERROR("\n Invalid input to free_ion_memory");
4358 return;
4359 }
4360 if (ioctl(buf_ion_info->ion_device_fd,ION_IOC_FREE,
4361 &buf_ion_info->ion_alloc_data.handle)) {
4362 DEBUG_PRINT_ERROR("\n ION free failed ");
4363 return;
4364 }
4365 close(buf_ion_info->ion_device_fd);
4366 buf_ion_info->ion_alloc_data.handle = NULL;
4367 buf_ion_info->ion_device_fd = -1;
4368 buf_ion_info->fd_ion_data.fd = -1;
4369 }
4370 #endif
4371 #endif
4372 #ifdef _ANDROID_ICS_
omx_release_meta_buffer(OMX_BUFFERHEADERTYPE * buffer)4373 void omx_video::omx_release_meta_buffer(OMX_BUFFERHEADERTYPE *buffer)
4374 {
4375 if(buffer && meta_mode_enable)
4376 {
4377 encoder_media_buffer_type *media_ptr;
4378 struct pmem Input_pmem;
4379 unsigned int index_pmem = 0;
4380 bool meta_error = false;
4381
4382 index_pmem = (buffer - m_inp_mem_ptr);
4383 if(mUseProxyColorFormat &&
4384 (index_pmem < m_sInPortDef.nBufferCountActual)) {
4385 if(!dev_free_buf((&m_pInput_pmem[index_pmem]),PORT_INDEX_IN)){
4386 DEBUG_PRINT_ERROR("\n omx_release_meta_buffer dev free failed");
4387 }
4388 } else {
4389 media_ptr = (encoder_media_buffer_type *) buffer->pBuffer;
4390 if(media_ptr && media_ptr->meta_handle)
4391 {
4392 if(media_ptr->buffer_type == kMetadataBufferTypeCameraSource &&
4393 media_ptr->meta_handle->numFds == 1 &&
4394 media_ptr->meta_handle->numInts == 2) {
4395 Input_pmem.fd = media_ptr->meta_handle->data[0];
4396 Input_pmem.buffer = media_ptr;
4397 Input_pmem.size = media_ptr->meta_handle->data[2];
4398 Input_pmem.offset = media_ptr->meta_handle->data[1];
4399 DEBUG_PRINT_LOW("EBD fd = %d, offset = %d, size = %d",Input_pmem.fd,
4400 Input_pmem.offset,
4401 Input_pmem.size);
4402 } else if(media_ptr->buffer_type == kMetadataBufferTypeGrallocSource) {
4403 private_handle_t *handle = (private_handle_t *)media_ptr->meta_handle;
4404 Input_pmem.buffer = media_ptr;
4405 Input_pmem.fd = handle->fd;
4406 Input_pmem.offset = 0;
4407 Input_pmem.size = handle->size;
4408 } else {
4409 meta_error = true;
4410 DEBUG_PRINT_ERROR(" Meta Error set in EBD");
4411 }
4412 if(!meta_error)
4413 meta_error = !dev_free_buf(&Input_pmem,PORT_INDEX_IN);
4414 if(meta_error)
4415 {
4416 DEBUG_PRINT_ERROR(" Warning dev_free_buf failed flush value is %d",
4417 input_flush_progress);
4418 }
4419 }
4420 }
4421 }
4422 }
4423 #endif
omx_c2d_conv()4424 omx_video::omx_c2d_conv::omx_c2d_conv()
4425 {
4426 c2dcc = NULL;
4427 mLibHandle = NULL;
4428 mConvertOpen = NULL;
4429 mConvertClose = NULL;
4430 src_format = NV12_2K;
4431 }
4432
init()4433 bool omx_video::omx_c2d_conv::init() {
4434 bool status = true;
4435 if(mLibHandle || mConvertOpen || mConvertClose) {
4436 DEBUG_PRINT_ERROR("\n omx_c2d_conv::init called twice");
4437 status = false;
4438 }
4439 if(status) {
4440 mLibHandle = dlopen("libc2dcolorconvert.so", RTLD_LAZY);
4441 if(mLibHandle){
4442 mConvertOpen = (createC2DColorConverter_t *)
4443 dlsym(mLibHandle,"createC2DColorConverter");
4444 mConvertClose = (destroyC2DColorConverter_t *)
4445 dlsym(mLibHandle,"destroyC2DColorConverter");
4446 if(!mConvertOpen || !mConvertClose)
4447 status = false;
4448 } else
4449 status = false;
4450 }
4451 if(!status && mLibHandle){
4452 dlclose(mLibHandle);
4453 mLibHandle = NULL;
4454 mConvertOpen = NULL;
4455 mConvertClose = NULL;
4456 }
4457 return status;
4458 }
4459
convert(int src_fd,void * src_base,void * src_viraddr,int dest_fd,void * dest_base,void * dest_viraddr)4460 bool omx_video::omx_c2d_conv::convert(int src_fd, void *src_base, void *src_viraddr,
4461 int dest_fd, void *dest_base, void *dest_viraddr)
4462 {
4463 int result;
4464 if(!src_viraddr || !dest_viraddr || !c2dcc){
4465 DEBUG_PRINT_ERROR("\n Invalid arguments omx_c2d_conv::convert");
4466 return false;
4467 }
4468 result = c2dcc->convertC2D(src_fd, src_base, src_viraddr,
4469 dest_fd, dest_base, dest_viraddr);
4470 DEBUG_PRINT_LOW("\n Color convert status %d",result);
4471 return ((result < 0)?false:true);
4472 }
4473
open(unsigned int height,unsigned int width,ColorConvertFormat src,ColorConvertFormat dest,unsigned int srcStride)4474 bool omx_video::omx_c2d_conv::open(unsigned int height,unsigned int width,
4475 ColorConvertFormat src, ColorConvertFormat dest,
4476 unsigned int srcStride)
4477 {
4478 bool status = false;
4479 if(!c2dcc) {
4480 c2dcc = mConvertOpen(width, height, width, height,
4481 src, dest, 0, srcStride);
4482 if(c2dcc) {
4483 src_format = src;
4484 status = true;
4485 } else
4486 DEBUG_PRINT_ERROR("\n mConvertOpen failed");
4487 }
4488 return status;
4489 }
close()4490 void omx_video::omx_c2d_conv::close()
4491 {
4492 if(mLibHandle) {
4493 if(mConvertClose && c2dcc)
4494 mConvertClose(c2dcc);
4495 c2dcc = NULL;
4496 }
4497 }
~omx_c2d_conv()4498 omx_video::omx_c2d_conv::~omx_c2d_conv()
4499 {
4500 DEBUG_PRINT_ERROR("\n Destroy C2D instance");
4501 if(mLibHandle) {
4502 if(mConvertClose && c2dcc)
4503 mConvertClose(c2dcc);
4504 dlclose(mLibHandle);
4505 }
4506 c2dcc = NULL;
4507 mLibHandle = NULL;
4508 mConvertOpen = NULL;
4509 mConvertClose = NULL;
4510 }
get_src_format()4511 int omx_video::omx_c2d_conv::get_src_format()
4512 {
4513 int format = -1;
4514 if(src_format == NV12_2K) {
4515 format = HAL_PIXEL_FORMAT_NV12_ENCODEABLE;
4516 } else if(src_format == RGBA8888) {
4517 format = HAL_PIXEL_FORMAT_RGBA_8888;
4518 }
4519 return format;
4520 }
get_buffer_size(int port,unsigned int & buf_size)4521 bool omx_video::omx_c2d_conv::get_buffer_size(int port,unsigned int &buf_size)
4522 {
4523 int cret = 0;
4524 bool ret = false;
4525 C2DBuffReq bufferreq;
4526 if(c2dcc){
4527 bufferreq.size = 0;
4528 cret = c2dcc->getBuffReq(port,&bufferreq);
4529 DEBUG_PRINT_LOW("\n Status of getbuffer is %d", cret);
4530 ret = (cret)?false:true;
4531 buf_size = bufferreq.size;
4532 }
4533 return ret;
4534 }
empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,OMX_IN OMX_BUFFERHEADERTYPE * buffer)4535 OMX_ERRORTYPE omx_video::empty_this_buffer_opaque(OMX_IN OMX_HANDLETYPE hComp,
4536 OMX_IN OMX_BUFFERHEADERTYPE* buffer)
4537 {
4538 unsigned nBufIndex = 0;
4539 OMX_ERRORTYPE ret = OMX_ErrorNone;
4540 encoder_media_buffer_type *media_buffer;
4541 DEBUG_PRINT_LOW("\n ETBProxyOpaque: buffer[%p]\n", buffer);
4542
4543 if(buffer == NULL) {
4544 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid buffer[%p]\n",buffer);
4545 return OMX_ErrorBadParameter;
4546 }
4547 nBufIndex = buffer - meta_buffer_hdr;
4548 if(nBufIndex >= m_sInPortDef.nBufferCountActual) {
4549 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Invalid bufindex = %u\n",
4550 nBufIndex);
4551 return OMX_ErrorBadParameter;
4552 }
4553 media_buffer = (encoder_media_buffer_type *)buffer->pBuffer;
4554 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4555 /*Enable following code once private handle color format is
4556 updated correctly*/
4557
4558 if(buffer->nFilledLen > 0) {
4559 if(c2d_opened && handle->format != c2d_conv.get_src_format()) {
4560 c2d_conv.close();
4561 c2d_opened = false;
4562 }
4563 if (!c2d_opened) {
4564 if (handle->format == HAL_PIXEL_FORMAT_RGBA_8888) {
4565 DEBUG_PRINT_ERROR("\n open Color conv for RGBA888");
4566 if(!c2d_conv.open(m_sInPortDef.format.video.nFrameHeight,
4567 m_sInPortDef.format.video.nFrameWidth,RGBA8888,NV12_2K,
4568 (unsigned int)handle->width)){
4569 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4570 DEBUG_PRINT_ERROR("\n Color conv open failed");
4571 return OMX_ErrorBadParameter;
4572 }
4573 c2d_opened = true;
4574 } else if(handle->format != HAL_PIXEL_FORMAT_NV12_ENCODEABLE) {
4575 DEBUG_PRINT_ERROR("\n Incorrect color format");
4576 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4577 return OMX_ErrorBadParameter;
4578 }
4579 }
4580 }
4581
4582 if(input_flush_progress == true)
4583 {
4584 m_pCallbacks.EmptyBufferDone(hComp,m_app_data,buffer);
4585 DEBUG_PRINT_ERROR("\nERROR: ETBProxyA: Input flush in progress");
4586 return OMX_ErrorNone;
4587 }
4588
4589 if(!psource_frame) {
4590 psource_frame = buffer;
4591 ret = push_input_buffer(hComp);
4592 } else {
4593 if (!m_opq_meta_q.insert_entry((unsigned)buffer,0,0)) {
4594 m_pCallbacks.EmptyBufferDone(hComp, m_app_data, buffer);
4595 DEBUG_PRINT_ERROR("\nERROR: ETBProxy: Queue is full");
4596 ret = OMX_ErrorBadParameter;
4597 }
4598 }
4599 return ret;
4600 }
queue_meta_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info)4601 OMX_ERRORTYPE omx_video::queue_meta_buffer(OMX_HANDLETYPE hComp,
4602 struct pmem &Input_pmem_info) {
4603
4604 OMX_ERRORTYPE ret = OMX_ErrorNone;
4605 unsigned address = 0,p2,id;
4606
4607 DEBUG_PRINT_LOW("\n In queue Meta Buffer");
4608 if(!psource_frame || !pdest_frame) {
4609 DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4610 return OMX_ErrorBadParameter;
4611 }
4612
4613 if(psource_frame->nFilledLen > 0) {
4614 if(dev_use_buf(&Input_pmem_info,PORT_INDEX_IN,0) != true) {
4615 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4616 post_event ((unsigned int)psource_frame,0,OMX_COMPONENT_GENERATE_EBD);
4617 ret = OMX_ErrorBadParameter;
4618 }
4619 }
4620
4621 if(ret == OMX_ErrorNone)
4622 ret = empty_this_buffer_proxy(hComp,psource_frame);
4623
4624 if(ret == OMX_ErrorNone) {
4625 psource_frame = NULL;
4626 if(!psource_frame && m_opq_meta_q.m_size) {
4627 m_opq_meta_q.pop_entry(&address,&p2,&id);
4628 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4629 }
4630 } else {
4631 // there has been an error and source frame has been scheduled for an EBD
4632 psource_frame = NULL;
4633 }
4634 return ret;
4635 }
4636
convert_queue_buffer(OMX_HANDLETYPE hComp,struct pmem & Input_pmem_info,unsigned & index)4637 OMX_ERRORTYPE omx_video::convert_queue_buffer(OMX_HANDLETYPE hComp,
4638 struct pmem &Input_pmem_info,unsigned &index){
4639
4640 unsigned char *uva;
4641 OMX_ERRORTYPE ret = OMX_ErrorNone;
4642 unsigned address = 0,p2,id;
4643
4644 DEBUG_PRINT_LOW("\n In Convert and queue Meta Buffer");
4645 if(!psource_frame || !pdest_frame) {
4646 DEBUG_PRINT_ERROR("\n convert_queue_buffer invalid params");
4647 return OMX_ErrorBadParameter;
4648 }
4649
4650 if(!psource_frame->nFilledLen){
4651 if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS){
4652 pdest_frame->nFilledLen = psource_frame->nFilledLen;
4653 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4654 pdest_frame->nFlags = psource_frame->nFlags;
4655 DEBUG_PRINT_HIGH("\n Skipping color conversion for empty EOS \
4656 Buffer header=%p filled-len=%d", pdest_frame,pdest_frame->nFilledLen);
4657 } else {
4658 pdest_frame->nOffset = 0;
4659 pdest_frame->nFilledLen = 0;
4660 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4661 pdest_frame->nFlags = psource_frame->nFlags;
4662 DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4663 pdest_frame,pdest_frame->nFilledLen);
4664 }
4665 } else {
4666 uva = (unsigned char *)mmap(NULL, Input_pmem_info.size,
4667 PROT_READ|PROT_WRITE,
4668 MAP_SHARED,Input_pmem_info.fd,0);
4669 if(uva == MAP_FAILED) {
4670 ret = OMX_ErrorBadParameter;
4671 } else {
4672 if(!c2d_conv.convert(Input_pmem_info.fd, uva, uva,
4673 m_pInput_pmem[index].fd, pdest_frame->pBuffer, pdest_frame->pBuffer)) {
4674 DEBUG_PRINT_ERROR("\n Color Conversion failed");
4675 ret = OMX_ErrorBadParameter;
4676 } else {
4677 unsigned int buf_size = 0;
4678 if (!c2d_conv.get_buffer_size(C2D_OUTPUT,buf_size))
4679 ret = OMX_ErrorBadParameter;
4680 else {
4681 pdest_frame->nOffset = 0;
4682 if(!buf_size || buf_size > pdest_frame->nAllocLen) {
4683 DEBUG_PRINT_ERROR("\n convert_queue_buffer buffer"
4684 "size mismatch buf size %d alloc size %d",
4685 buf_size, pdest_frame->nAllocLen);
4686 ret = OMX_ErrorBadParameter;
4687 buf_size = 0;
4688 }
4689 pdest_frame->nFilledLen = buf_size;
4690 pdest_frame->nTimeStamp = psource_frame->nTimeStamp;
4691 pdest_frame->nFlags = psource_frame->nFlags;
4692 DEBUG_PRINT_LOW("\n Buffer header %p Filled len size %d",
4693 pdest_frame,pdest_frame->nFilledLen);
4694 }
4695 }
4696 munmap(uva,Input_pmem_info.size);
4697 }
4698 }
4699 if((ret == OMX_ErrorNone) &&
4700 dev_use_buf(&m_pInput_pmem[index],PORT_INDEX_IN,0) != true) {
4701 DEBUG_PRINT_ERROR("\nERROR: in dev_use_buf");
4702 post_event ((unsigned int)pdest_frame,0,OMX_COMPONENT_GENERATE_EBD);
4703 ret = OMX_ErrorBadParameter;
4704 }
4705 if(ret == OMX_ErrorNone)
4706 ret = empty_this_buffer_proxy(hComp,pdest_frame);
4707 if(ret == OMX_ErrorNone) {
4708 m_pCallbacks.EmptyBufferDone(hComp ,m_app_data, psource_frame);
4709 psource_frame = NULL;
4710 pdest_frame = NULL;
4711 if(!psource_frame && m_opq_meta_q.m_size) {
4712 m_opq_meta_q.pop_entry(&address,&p2,&id);
4713 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4714 }
4715 if(!pdest_frame && m_opq_pmem_q.m_size) {
4716 m_opq_pmem_q.pop_entry(&address,&p2,&id);
4717 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4718 DEBUG_PRINT_LOW("\n pdest_frame pop address is %p",pdest_frame);
4719 }
4720 } else {
4721 // there has been an error and source frame has been scheduled for an EBD
4722 psource_frame = NULL;
4723 }
4724 return ret;
4725 }
4726
push_input_buffer(OMX_HANDLETYPE hComp)4727 OMX_ERRORTYPE omx_video::push_input_buffer(OMX_HANDLETYPE hComp)
4728 {
4729 unsigned address = 0,p2,id, index = 0;
4730 OMX_ERRORTYPE ret = OMX_ErrorNone;
4731
4732 if(!psource_frame && m_opq_meta_q.m_size) {
4733 m_opq_meta_q.pop_entry(&address,&p2,&id);
4734 psource_frame = (OMX_BUFFERHEADERTYPE* ) address;
4735 }
4736 if(!pdest_frame && m_opq_pmem_q.m_size) {
4737 m_opq_pmem_q.pop_entry(&address,&p2,&id);
4738 pdest_frame = (OMX_BUFFERHEADERTYPE* ) address;
4739 }
4740 while(psource_frame != NULL && pdest_frame != NULL &&
4741 ret == OMX_ErrorNone) {
4742 struct pmem Input_pmem_info;
4743 encoder_media_buffer_type *media_buffer;
4744 index = pdest_frame - m_inp_mem_ptr;
4745 if(index >= m_sInPortDef.nBufferCountActual){
4746 DEBUG_PRINT_ERROR("\n Output buffer index is wrong %d act count %d",
4747 index,m_sInPortDef.nBufferCountActual);
4748 return OMX_ErrorBadParameter;
4749 }
4750 media_buffer = (encoder_media_buffer_type *)psource_frame->pBuffer;
4751 /*Will enable to verify camcorder in current TIPS can be removed*/
4752 if(media_buffer->buffer_type == kMetadataBufferTypeCameraSource) {
4753 Input_pmem_info.buffer = media_buffer;
4754 Input_pmem_info.fd = media_buffer->meta_handle->data[0];
4755 Input_pmem_info.offset = media_buffer->meta_handle->data[1];
4756 Input_pmem_info.size = media_buffer->meta_handle->data[2];
4757 DEBUG_PRINT_LOW("ETB fd = %d, offset = %d, size = %d",Input_pmem_info.fd,
4758 Input_pmem_info.offset,
4759 Input_pmem_info.size);
4760 ret = queue_meta_buffer(hComp,Input_pmem_info);
4761 } else if(psource_frame->nFlags & OMX_BUFFERFLAG_EOS & mUseProxyColorFormat) {
4762 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4763 } else {
4764 private_handle_t *handle = (private_handle_t *)media_buffer->meta_handle;
4765 Input_pmem_info.buffer = media_buffer;
4766 Input_pmem_info.fd = handle->fd;
4767 Input_pmem_info.offset = 0;
4768 Input_pmem_info.size = handle->size;
4769 if(handle->format == HAL_PIXEL_FORMAT_RGBA_8888)
4770 ret = convert_queue_buffer(hComp,Input_pmem_info,index);
4771 else if(handle->format == HAL_PIXEL_FORMAT_NV12_ENCODEABLE)
4772 ret = queue_meta_buffer(hComp,Input_pmem_info);
4773 else
4774 ret = OMX_ErrorBadParameter;
4775 }
4776 }
4777 return ret;
4778 }
4779