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