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